AccessToken using an API key and signature mechanism, and then access the business APIs using the Bearer Token method.AccessToken using an API Key, a timestamp, and a signature.Authorization: Bearer <AccessToken> header.POST /cmd/GetAccessToken HTTP/1.1Host: <FHIR_SERVICE_HOST>Content-Type: application/json
<FHIR_SERVICE_HOST> is the domain name for accessing the authentication service. Refer to the instance access information in the Tencent Healthcare Data Services console or the service access address provided by the deployment party.<FHIR_SERVICE_HOST> in the example is a placeholder. Replace it with an actual accessible domain name when making calls, and do not use the placeholder directly to send requests.{"header": {"version": "v0.1","flag": 0},"body": {"seq": 0,"cmd": "","token": "","traceid": "","client": {"platform": 0,"env": "","isTourist": 0,"product": 0},"payload": {"timestamp": 1730000000000,"apiKey": "<API_KEY>","signature": "<SIGNATURE>","scopes": [],"context": {}}}}
timestamp is a millisecond-level Unix timestamp.signature is a signature value calculated based on the API Secret.scopes and context are extension fields and can be passed in based on the actual authorization scenario.POST: Creates a resource or submits a Bundle transaction/batch request.GET: Reads resources, reads historical versions, and performs searches.PUT: Updates the complete resource content.PATCH: Updates partial fields.DELETE: Deletes the specified resource.GET /INSTANCE_ID/fhir/Patient/199963 HTTP/1.1Host: HOSTNAMEAuthorization: Bearer <AccessToken>Accept: application/fhir+json
HOSTNAME is the FHIR service access domain name, and INSTANCE_ID is the FHIR service instance ID. Obtain them from the instance access information in the Tencent Healthcare Data Services console, or refer to the service access address provided by the deployment party.[baseUrl]/[resourceType] or [baseUrl]/[resourceType]/[id][baseUrl]/[resourceType]/[id]/_history/[versionId][baseUrl]/[resourceType]?[searchParams][baseUrl]/Patient/[id]/$everything[baseUrl]Parameter Name | Type | Required | Description |
header.version | String | Yes | Request protocol version. Example: v0.1. |
header.flag | Integer | Yes | Request flag. Example: 0. |
body.seq | Integer | Yes | Request sequence number. Example: 0. |
body.cmd | String | No | Reserved command field |
body.token | String | No | Reserved token field. It is usually empty when AccessToken is obtained. |
body.traceid | String | No | Request trace ID |
body.client.platform | Integer | No | Client platform identifier |
body.client.env | String | No | Calling environment identifier |
body.client.isTourist | Integer | No | Tourist identifier |
body.client.product | Integer | No | Product identifier |
body.payload.timestamp | Integer | Yes | Millisecond-level timestamp. The server allows a time window of 3600000 milliseconds (1 hour) before and after the request arrival time at the server. Requests outside this window are rejected. |
body.payload.apiKey | String | Yes | API Keys |
body.payload.signature | String | Yes | Signature value |
body.payload.scopes | Array | Conditionally Required | The requested permission scope. It is required when Informed Consent Access Control is enabled, and must contain at least one actor/<ResourceType>/<ID> (for example, "actor/Practitioner/P001"). Otherwise, accessing the FHIR API returns a 401 error (the scope field is missing in Claims). It can be left empty ([]) when not enabled. |
body.payload.context | Object | No | Context extension parameters |
Parameter Name | Type | Required | Description |
Host | String | Yes | The FHIR service access domain name, for example, HOSTNAME. Obtain it from the instance access information in the Tencent Healthcare Data Services console, or use the service access address provided by the deployment party. |
Authorization | String | Yes | The access token, in the format Bearer <AccessToken> |
Content-Type | String | No | The type of the request body. Write-type requests typically use application/fhir+json; Patch requests typically use application/json-patch+json. |
Accept | String | No | The response format. It is recommended to use application/fhir+json. |
resourceType | String | Depends on the API | The FHIR resource type, such as Patient, Observation, Encounter |
id | String | Depends on the API | The unique identifier for a resource |
searchParams | Query String | No | Search parameters, used to filter the result set |
versionId | String | No | The historical version ID, used in scenarios such as vRead |
API Key, API Secret, and a signature mechanism. The caller must first request an AccessToken from the authentication service and then access the FHIR APIs by including this token.API Key and API Secret corresponding to the service.timestamp.signature using a signature algorithm.apiKey, timestamp, and signature to the authentication API.AccessToken is returned.Authorization request header.AccessToken.message = apiKey + timestamp
signature = HMAC-SHA256(apiSecret, message)
message is encoded using UTF-8.timestamp is a millisecond-level timestamp.3600000 milliseconds (1 hour) before and after the request arrival time at the server:timestamp > server current time + 3600000, the request will be rejected.timestamp < server current time - 3600000, the request will be rejected.signTime is timed outsignature is invalidAccessToken, the caller must place it in the HTTP Header when accessing the FHIR API:Authorization: Bearer <AccessToken>
AuthorizationBearer <space><AccessToken>import hashlibimport hmacimport timefrom typing import Optionalimport requestsdef sign(api_key: str, api_secret: str, sign_time: int) -> str:SignatureArgs:api_key: API Keyapi_secret: Secret corresponding to the API Keysign_time: Signature time (in milliseconds)Returns:Signature string (uppercase hexadecimal)"""message = f"{api_key}{sign_time}".encode("utf-8")h = hmac.new(api_secret.encode("utf-8"), message, hashlib.sha256)return h.hexdigest().upper()# Signature Verification Logic (For Local Self-Testing)def check_signature(api_key: str, api_secret: str, signature: str, sign_time: int, timeout: int) -> Optional[str]:Verify SignatureArgs:api_key: API Keyapi_secret: Secret corresponding to the API Keysignature: Signature stringsign_time: Signature time (in milliseconds)timeout: Timeout duration (in milliseconds)Returns:A value of None indicates successful validation; otherwise, an error message is returned."""now_time = int(time.time() * 1000) # Current time (in milliseconds)if sign_time > now_time + timeout or sign_time < now_time - timeout:return "signTime is timed out"calculated_sign = sign(api_key, api_secret, sign_time)if signature.upper() != calculated_sign.upper():return "signature is invalid"return Nonedef request_auth_server(api_key: str, api_secret: str) -> Optional[str]:sign_time = int(time.time() * 1000)signature = sign(api_key, api_secret, sign_time)rsp = requests.post(# Replace <FHIR_SERVICE_HOST> with the actual authentication service access domain nameurl="https://<FHIR_SERVICE_HOST>/cmd/GetAccessToken",json={"header": {"version": "v0.1","flag": 0,},"body": {"seq": 0,"cmd": "","token": "","traceid": "","client": {"platform": 0,"env": "","isTourist": 0,"product": 0,},"payload": {"timestamp": sign_time,"apiKey": api_key,"signature": signature,"scopes": [],"context": {},},},},timeout=10,)if rsp.status_code != 200:return Nonedata = rsp.json()if data.get("retcode", 0) != 0:return Nonepayload = data.get("payload") or {}return payload.get("accessToken")if __name__ == "__main__":key = "<KEY>"secret = "<SECRET>"token = request_auth_server(key, secret)print(token)
accessToken. The caller should securely store this token and use it in subsequent FHIR requests. A sample of the returned result is as follows:{"payload": {"accessToken": "<ACCESS_TOKEN>"}}
200.accessToken is not returned in the response.Bundle.OperationOutcome or a status result.Bundle.Parameter Name | Description |
Status Code | HTTP status code, used to identify the request processing result. |
ETag | Resource version identifier |
Location / Content-Location | Access address for the resource or its historical versions |
Status Code, ETag, and Location.Bundle.entry, Bundle.total, and Bundle.link.OperationOutcome or the error response body.Was this page helpful?
You can also Contact sales or Submit a Ticket for help.
Help us improve! Rate your documentation experience in 5 mins.
Feedback