Table of Contents #
- Overview
- Authentication
2.1 Test (Development) Authentication
2.2 Production Authentication
2.3 Example PHP Encryption - Endpoints
3.1 Get Offices
3.2 Get Patients
3.3 Get Patient
3.4 Get Case
3.5 Create Case - Webhook Notifications
4.1 Webhook Authentication
4.2 Decrypting Webhook Authorization
4.3 Webhook Security Validation - Security Notes
Overview #
The Titan Labs API allows secure interaction with Titan’s dental laboratory services, enabling you to manage offices, patients, and cases. All communication uses HTTPS, and requests must be authorized using one of the two supported methods:
- Development environment (using
TestAuthorization
) - Production environment (using
Authorization
with AES-256-CBC encrypted token)
Authentication #
Titan Labs supports two authentication methods. Depending on your use case (development vs. production), you must include one of the following HTTP headers in your requests:
TestAuthorization
Authorization
Authentication Keys #
- Public Key:
a3f4dd81f9294a9688a37ab24685c3a3
- Private Key:
1379dd8aa9236f95882b6abc46d5c3a1
Test (Development) Authentication #
In the development/testing environment, simply provide the header:
TestAuthorization: PublicKey-PrivateKey
Example:
TestAuthorization: a3f4dd81f9294a9688a37ab24685c3a3-1379dd8aa9236f95882b6abc46d5c3a1
Production Authentication #
In the production environment, you must encrypt a timestamped string using AES-256-CBC with the private key. The string to encrypt is composed of:
public_key-YYYY-mm-dd HH:ii:ss (UTC time)
After encrypting this string, place the resulting value in the Authorization
header.
Example (unencrypted format to be encrypted):
a3f4dd81f9294a9688a37ab24685c3a3-2024-11-03 21:05:01
Then send the encrypted value:
Authorization: <AES-256-CBC base64-encoded string>
Example PHP Encryption #
Below is a sample PHP function that demonstrates how to encrypt a string using AES-256-CBC:
function encrypt_AES_256_CBC($data, $key): string
{
$cipher = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($cipher);
if ($ivlen === false)
return false;
$iv = openssl_random_pseudo_bytes($ivlen);
$encrypted = openssl_encrypt($data, $cipher, $key, 0, $iv);
if ($encrypted === false)
return false;
return base64_encode($iv . $encrypted);
}
Endpoints #
Below are the core endpoints for managing offices, patients, and cases.
All endpoints are prefixed with:
https://server.titandentaldesign.com/cloud/Dev/api/lab.php
Important:
- Include the appropriate authentication header (
TestAuthorization
orAuthorization
) for each request. - Query parameters are appended using
?
and&
as shown in the examples below.
Get Offices #
Retrieves a list of dental offices.
HTTP Method: GET
Endpoint:
GET /cloud/Dev/api/lab.php?action=get_offices
Example Request:
GET https://server.titandentaldesign.com/cloud/Dev/api/lab.php?action=get_offices
Headers:
TestAuthorization: a3f4dd81f9294a9688a37ab24685c3a3-1379dd8aa9236f95882b6abc46d5c3a1
(or use Authorization
for production)
Query Parameters: None
Get Patients #
Retrieves a paginated list of patients with optional filtering.
HTTP Method: GET
Endpoint:
GET /cloud/Dev/api/lab.php?action=get_patients
Example Request:
GET https://server.titandentaldesign.com/cloud/Dev/api/lab.php?action=get_patients&patient=&patient_id=&page=1&page_size=10
Headers:
TestAuthorization: a3f4dd81f9294a9688a37ab24685c3a3-1379dd8aa9236f95882b6abc46d5c3a1
(or use Authorization
for production)
Query Parameters:
patient
(optional) Filter by patient name (e.g.,"smith"
) or leave it empty to return all.patient_id
(optional) Filter by external patient ID.page
(default:1
) Page number for pagination.page_size
(default:10
) Number of records per page.
Get Patient #
Retrieves detailed information for a specific patient.
HTTP Method: GET
Endpoint:
GET /cloud/Dev/api/lab.php?action=get_patient&patient_id={id}
Example Request:
GET https://server.titandentaldesign.com/cloud/Dev/api/lab.php?action=get_patient&patient_id=a1b
Headers:
TestAuthorization: a3f4dd81f9294a9688a37ab24685c3a3-1379dd8aa9236f95882b6abc46d5c3a1
(or use Authorization
for production)
Query Parameters:
action
:get_patient
patient_id
: Unique identifier for the patient (e.g.,a1b
)
Get Case #
Retrieves information for a specific case.
HTTP Method: GET
Endpoint:
GET /cloud/Dev/api/lab.php?action=get_case&case_id={id}
Example Request:
GET https://server.titandentaldesign.com/cloud/Dev/api/lab.php?action=get_case&case_id=1122
Headers:
TestAuthorization: a3f4dd81f9294a9688a37ab24685c3a3-1379dd8aa9236f95882b6abc46d5c3a1
(or use Authorization
for production)
Query Parameters:
action
:get_case
case_id
: Unique identifier for the case (e.g.,1122
)
Create Case #
Creates a new case for a given patient. If the patient does not yet exist, you can pass the required fields to create the patient record.
HTTP Method: POST
Endpoint:
POST /cloud/Dev/api/lab.php
Example Request (Form Data):
POST https://server.titandentaldesign.com/cloud/Dev/api/lab.php
Headers:
TestAuthorization: a3f4dd81f9294a9688a37ab24685c3a3-1379dd8aa9236f95882b6abc46d5c3a1
(or use Authorization
for production)
Form Data Parameters (multipart/form-data):
- action:
create_case
- patient_id: Unique identifier for an existing patient.
- case_id: Unique case identifier.
- instructions: Instructions for the case.
- account_email (required if creating a new patient): Email of the account to associate with the new patient.
- patient_name (required if creating a new patient): First name of the new patient.
- patient_lastname (required if creating a new patient): Last name of the new patient.
- files: A zip file with one or more file attachments (X-rays, documents, etc.) to be included with the case.
- gender (optional). Can be ‘Male’, ‘Female’, etc
- birthday (optional) Example: ‘2010-01-28’
- star_color (optional) One of: ‘White’,’Red’,’Green’,’Blue’,’Yellow’,’Cyan’
Share Case #
Re-creates the Doctor and/or patient Shared link for a specific case.
HTTP Method: GET
Endpoint:
GET /cloud/Dev/api/lab.php?action=share_case&case_id={id}
GET /cloud/Dev/api/lab.php?action=share_case&case_id={id}&patient=1
Example Request:
GET https://server.titandentaldesign.com/cloud/Dev/api/lab.php?action=get_case&case_id=1122
Headers:
TestAuthorization: a3f4dd81f9294a9688a37ab24685c3a3-1379dd8aa9236f95882b6abc46d5c3a1
(or use Authorization
for production)
Query Parameters:
action
:get_case
case_id
: Unique identifier for the case (e.g.,1122
)- patient_id: When patient_id is 1, the request will update the Patient Shared link, otherwise, it will update the Doctor shared link.
Webhook Notifications #
Titan Labs can send webhook notifications to your application’s configured URL whenever certain events occur (e.g., new case creation, status changes, printing updates, etc.).
Webhook Authentication #
Each webhook request includes an Authorization
header containing an AES-256-CBC encrypted token. This token is constructed in a format similar to the API’s production authentication mechanism.
Example header (encrypted token):
Authorization: a3f4dd81f9294a9688a37ab24685c3a3-1379dd8aa9236f95882b6abc46d5c3a1
Decrypting Webhook Authorization #
Use the following PHP function to decrypt the webhook authorization header. The decrypted string typically looks like:
API_PUBLIC_2024-10-18 03:03:03
Where:
API_PUBLIC
is a prefix that indicates a valid Titan Labs webhook call- The datetime is in UTC format
function decrypt_AES_256_CBC($encryptedData, $key): false|string {
$cipher = "aes-256-cbc";
$data = base64_decode($encryptedData);
$ivlen = openssl_cipher_iv_length($cipher);
if ($ivlen === false)
return false;
$iv = substr($data, 0, $ivlen);
$encryptedData = substr($data, $ivlen);
return openssl_decrypt($encryptedData, $cipher, $key, 0, $iv);
}
Webhook Security Validation #
When handling an incoming webhook:
- Decrypt the
Authorization
header using your private key. - Verify the decrypted string starts with
API_PUBLIC
. - Extract the UTC datetime and check that the request is recent enough (to prevent replay attacks).
- Reject any requests that fail these validations.
Security Notes #
- Never transmit or expose the private key publicly.
- The
Authorization
tokens include timestamps to prevent replay attacks; always verify recency. - All datetime values should be in UTC.
- Webhooks should always be validated by decrypting the
Authorization
header and verifying the payload.
Webhooks will send notifications when several events happen in Titan. Here is a list of some of these events and the data that will be received:
New Lab Order : Sent when a new Planning Request is created.
POST Data:
parameter 'action': LabOrder_StatusChanged
parameter 'notification': {
"ExternalId": null,
"Status": "InQueue"
}
Lab Order Changed Status : When an order changes (e.g. is now in Review, InQueue, Supervisor, etc)
POST Data:
parameter 'action': LabOrder_StatusChanged
parameter 'notification': {
"ExternalId": null,
"Status": "Supervisor"
}
For questions or additional information, please contact:
- Email: support@titandentaldesign.com
- Website: Titan Dental Design
Last Updated: 2024-12-27