Titan Dental Design

View Categories

Titan Labs API

Table of Contents #

  1. Overview
  2. Authentication
    2.1 Test (Development) Authentication
    2.2 Production Authentication
    2.3 Example PHP Encryption
  3. Endpoints
    3.1 Get Offices
    3.2 Get Patients
    3.3 Get Patient
    3.4 Get Case
    3.5 Create Case
  4. Webhook Notifications
    4.1 Webhook Authentication
    4.2 Decrypting Webhook Authorization
    4.3 Webhook Security Validation
  5. 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 or Authorization) 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:

  1. Decrypt the Authorization header using your private key.
  2. Verify the decrypted string starts with API_PUBLIC.
  3. Extract the UTC datetime and check that the request is recent enough (to prevent replay attacks).
  4. Reject any requests that fail these validations.

Security Notes #

  1. Never transmit or expose the private key publicly.
  2. The Authorization tokens include timestamps to prevent replay attacks; always verify recency.
  3. All datetime values should be in UTC.
  4. 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:

Last Updated: 2024-12-27