# `/api/auth`


## `/api/auth/login`
Gets jwt token used to access non-auth endoints

METHOD: POST

BODY:
```js
{
    "email": "test@gmail.com",
    "password": "password"
}
```

Returns
```js
{
    "token": "XXXXXXXXXXXXXXXXXXXXXXXX..."
}
```

## `/api/auth/register`
Adds a user in database that can be used in `/api/auth/login`

METHOD: POST

BODY:
```js
{
    "first_name": "John",
    "last_name": "Smith",
    "address": "123 Main Street",
    "phone_number": "023456789",
    "email": "test@gmail.com",
    "password": "password"
}
```


# `/api/publicKey`


## `/api/publicKey`
Get the public key used by the AI system for encryption

METHOD: GET
AUTH: Bearer Token

Returns
```js
{
    "publicKey": "XXXXXXXXXXXXXXXXXXXXXXXX..."
}
```


# `/api/calls`


## `/api/calls/`
Gets calls from the database that ended since the last timestamp. If no timestamp than returns all calls

METHOD: GET
AUTH: Bearer Token
HEADER: Client-Public-Key

OPTIONAL
PARAMS: timestamp=2025-12-01T00:30:00Z

Returns
```js
[
 {
    "id": 'fa608944-27c1-40b3-824b-bc23b164361f',
    "patient_name": 'John Smith', // UNKNOWN if not found
    "patient_id": "c8547fdd-f915-46b7-8cfd-cc3a79df2b28",
    "call_sid": 'CA140f6b50e1b986a500a0795078829102',
    "date_of_birth": "10 Mar 2000",
    "phone_number": '0275556799',
    "clinic_name": 'St Martins Medical Practice',
    "status": 'TIMED_OUT',
    "call_type": [ 'prescriptions' ],
    "created_at": '2025-12-03T00:50:04.599Z',
    "ended_at": '2025-12-03T00:51:53.133Z',
    "ai_duration": 91, // time caller spends with AI
    "pharmacist_duration": 134, // time caller spends with a pharmacist
    "urgency": 3,
    "verification": 'NO_VERIFICATION',
    "contact_number": "0212345678", // will only be populated if caller id is private
    "caller_name": 'John Smith',
    "patient_firstname": "John", // first name of patient the call is about
    "patient_lastname": "Smith", // last name of patient the call is about
    "ai_summary": 'John Smith called at...',
    "first_message": 'I want to check if my.', // the initial request
    "user_messages": `Hi, please call me back at...`, // the message left by the user after speaking with AI
    "prescription_call_backs": [ // if user wants a text back for a prescription, it is included here
      {
        "prescription_id": '0cde57e0-c7c9-4476-8ae9-838650ffd8c7',
        "text_back_number": null
      },
      {
        "prescription_id": 'adc78916-a8dd-44f4-bf57-cf5bbcfa1c21',
        "text_back_number": null
      }
    ]
  }
]
```

## `/api/calls/:id`
Gets the transcription of a call using its id

METHOD: GET
AUTH: Bearer Token
HEADER: Client-Public-Key

Returns
```js
[
  {
    "speaker": 'assistant',
    "message": "Hello, I'm Charlie, your pharmacy assistant. How can I help you today?",
    "created_at": '2025-12-02T00:52:31.929Z'
  },
  {
    "speaker": 'user',
    "message": 'Repeat.',
    "created_at": '2025-12-02T00:52:40.816Z'
  },
  {
    "speaker": 'assistant',
    "message": 'Is this request for yourself or your child?',
    "created_at": '2025-12-02T00:52:40.816Z'
  },
  {
    "speaker": 'user',
    "message": 'Myself.',
    "created_at": '2025-12-02T00:52:47.507Z'
  }
]
```

### Notes:
:id = call id from database


## `/api/calls/getRecording`
Gets the wav file of a recording

METHOD: GET
AUTH: Bearer Token
HEADER: 
- Client-Public-Key
- callSid

Returns: Buffer of compressed zip folder hoding the wav file on the recording

## `/api/calls/verify`
Create a verified patient and number relation

METHOD: POST
AUTH: Bearer Token
HEADER: 
- Client-Public-Key

BODY:
```js
{
    "patientId": "c8547fdd-f915-46b7-8cfd-cc3a79df2b28",
    "callId": "f646174b-5d9f-45f0-9e36-19dc387edfbb",
    "type": "patient", // patient | medical | unverify
}
```

type:
- patient: number belongs to verified patient
- medical: number belongs to verified medical centre
- unverify: remove verification between a number and patient


# `/api/patients`


## `/api/patients/`
Gets all patients in the database

METHOD: GET
AUTH: Bearer Token
HEADER: Client-Public-Key

Returns
```js
[
  {
    "id": 'd51f2d94-6e11-4316-8955-7335578a7284',
    "email": 'test@example.com',
    "first_name": 'Jonathan',
    "last_name": 'Smith',
    "nhi": 'ABC95644',
    "landline_number": "091234567",
    "phone_number": '0212345678',
    "address": '110 Great South Road',
    "date_of_birth": '10 Mar 2001'
  }
]
```

## `/api/patients/update`
Adds a new patient if there is no id.
If an id is provided or NHI matches with a current patient that patient will be updated.
Patient details will be updated using the provided details. If any detail is missing, that detail will not be updated.

METHOD: POST
AUTH: Bearer Token
HEADER: Client-Public-Key

BODY:
```js
{
    "id" : "c8547fdd-f915-46b7-8cfd-cc3a79df2b28",
    "email": "test@example.com",
    "first_name": "John", // Not Nullable
    "last_name": "Smith",
    "nhi": "ABC95644",
    "phone_number": "0212345678",
    "address": "100 Great South Road",
    "date_of_birth": "10/03/2000", // DD/MM/YYYY
}
```

Returns
```js
"c8547fdd-f915-46b7-8cfd-cc3a79df2b28"
```

### Notes:
- Is is possible that the returned id does not match the input id. If that is the case, the returned id should be considered the new id for this patient.

## `/api/patients/:id`
Gets a patient using their id

METHOD: GET
AUTH: Bearer Token
HEADER: Client-Public-Key

Returns
```js
{
  "email": 'john.smith@example.com',
  "first_name": 'John',
  "last_name": 'Smith',
  "nhi": 'ABC1234',
  "landline_number": "091234567",
  "phone_number": '027 536 5355',
  "address": '100 Great South Road',
  "date_of_birth": '10 Mar 2000'
}
```

### Notes:
:id = patient id from database


## `/api/patients/:id/calls`
Gets every call associated with a patient

METHOD: GET
AUTH: Bearer Token
HEADER: Client-Public-Key

Returns
```js
[
  {
    id: '59981c38-7e0d-4d70-81bc-8ab19a210831',
    call_sid: 'CA061b8dd51579ef1bcdbd5d9f9c2c41de',
    phone_number: '0275556799',
    status: 'VERIFIED',
    created_at: '2025-11-30T20:59:17.619Z',
    ended_at: '2025-11-30T20:59:45.377Z'
  },
  {
    id: 'ec45fb80-c75d-4753-a95e-ae81f3e2059b',
    call_sid: 'CA96db3ec2841ad3fb3b3082ced5214978',
    phone_number: '0275556799',
    status: 'VERIFIED',
    created_at: '2025-11-30T20:56:27.148Z',
    ended_at: '2025-11-30T20:59:18.313Z'
  }
]
```

### Notes:
:id = patient id from database

## `/api/patients/updatePin`
If the number already has a pin linked with it the pin will get updated, otherwise it will create a new pin

METHOD: POST
AUTH: Bearer Token

BODY:
```js
{
    "patientId": "366d23eb-6132-452a-bffa-6422fff81c98",
    "number": "0275556799",
    "newPin": "1234"
}
```


# `/api/prescriptions`


## `/api/prescriptions/`
Gets prescriptions from the database that where created since the last timestamp. If no timestamp than returns all prescriptions

METHOD: GET
AUTH: Bearer Token
HEADER: Client-Public-Key

OPTIONAL
PARAMS: timestamp=2025-12-01T00:30:00Z

Returns
```js
[
  {
    "patient_id": "8193ec30-f8cc-4557-83c5-23ce87fa3a93",
    "clinic_name": "St Martins Medical Practice",
    "first_name": "Warwick",
    "last_name": "Kerr",
    "address": "110 Rotoiti Lane, Northwood, Christchurch, 8051",
    "phone_number": "027 347 2900",
    "nhi": "ADM0300",
    "created_at": "2025-10-14T02:23:13.114Z",
    "prescription_id": "dcd21f1d-f2c8-479d-9c64-b6bdc826445c",
    "prescription_status": "pending",
    "medications": [
      {
        "repeats_left": 7,
        "medication_name": "Bplex Tab"
      },
      {
        "medication_name": "Ascorbic Acid 100mg Tab"
      },
      {
        "repeats_left": 7,
        "medication_name": "Retrieve 0.05% Crm 50g"
      }
    ]
  }
]
```

## `/api/prescriptions/getPrescription`
Gets a prescription using prescriptionId from the header

METHOD: GET
AUTH: Bearer Token
HEADER: 
- Client-Public-Key
- prescriptionId


Returns
```js
{
  "patient_id": '6eb367c1-ad81-4d3b-a795-e76c2190c194',
  "clinic_name": 'St Martins Medical Practice',
  "first_name": 'Josh',
  "last_name": 'Lord',
  "address": '10 Rotoiti Lane, Northwood, Christchurch, 8051',
  "phone_number": '027 536 5355',
  "date_of_birth": '11 Oct 1976',
  "nhi": 'QWE6436',
  "created_at": '2025-10-09T01:39:51.886Z',
  "script_date": '2025-10-09',
  "prescription_id": '33a716bc-a2a8-4091-869c-b227579895cd',
  "prescription_status": 'ready',
  "medications": [
    { "repeats_left": 2, "medication_name": 'Rosuvastatin 10mg Tab' },
    { "repeats_left": 2, "medication_name": 'Omeprazole 20mg Cap' }
  ]
}
```


## `/api/prescriptions/updatePrescription`
Sets a prescription status to 'ready'

METHOD: POST
AUTH: Bearer Token
BODY:
```js
{ 
  "prescription_id": '33a716bc-a2a8-4091-869c-b227579895cd' 
}
```


## `/api/prescriptions/collectPrescription`
Sets a prescription status to 'completed'

METHOD: POST
AUTH: Bearer Token
BODY:
```js
{ 
  "prescription_id": '33a716bc-a2a8-4091-869c-b227579895cd' 
}
```


## `/api/prescriptions/updateStatusPrompt`
Updates what the system says when reading out the status of a prescription

METHOD: POST
AUTH: Bearer Token
BODY:
```js
{
  "prescription_id": '33a716bc-a2a8-4091-869c-b227579895cd',
  "status": 'prescription is delayed'
}
```


## `/api/prescriptions/matchPrescription`
Returns list of prescriptions that match provided details

METHOD: POST
AUTH: Bearer Token
HEADER: Client-Public-Key
BODY:
```js
{
    "nhi": "ABC1234",
    "medications": [
        "Omeprazole 20mg Cap",
        "Rosuvastatin 10mg Tab"
    ]
}
```

Returns
```js
[
  {
    "patient_id": "c8547fdd-f915-46b7-8cfd-cc3a79df2b28",
    "clinic_name": "St Martins Medical Practice",
    "first_name": "John",
    "last_name": "Smith",
    "address": "100 Great South Road",
    "phone_number": "027 536 5355",
    "nhi": "ABC1234",
    "created_at": "2025-10-09T01:39:51.886Z",
    "prescription_id": "0cde57e0-c7c9-4476-8ae9-838650ffd8c7",
    "prescription_status": "completed",
    "medications": [
      "Rosuvastatin 10mg Tab",
      "Omeprazole 20mg Cap"
    ]
  }
]
```


## `/api/prescriptions/addRepeats`
Adds repeats to a prescription

METHOD: POST
AUTH: Bearer Token
BODY:
```js
{
  id: '15033777-b995-49b0-be3d-af062307cbc7',
  repeats: [ 'Omeprazole 20mg Cap', 'Rosuvastatin 10mg Tab' ]
}
```


# `/api/clinics`


## `/api/clinics/get/:option`
METHOD: GET
AUTH: Bearer Token
HEADER: Client-Public-Key

Use to get the current value of settings that can be updated with clinics/options. The current options are:
- opening_hours
- pharmacy_details
- keywords
- services
- number_whitelist
- greeting
- read_medicines
- location_instructions
- holiday_hours

### greeting, read_medicines, location_instructions, holiday_hours
Returns
```js
"Hi, this is chloe..." // any string
```

### opening_hours
Returns
```js
[
    {
        "day": "Monday",
        "open_time": "8:00 am",
        "close_time": "6:00 pm",
        "is_closed": false
    },
    {
        "day": "Tuesday",
        "open_time": "8:00 am",
        "close_time": "6:00 pm",
        "is_closed": false
    },
    {
        "day": "Wednesday",
        "open_time": "8:00 am",
        "close_time": "6:00 pm",
        "is_closed": false
    },
    {
        "day": "Thursday",
        "open_time": "8:00 am",
        "close_time": "6:00 pm",
        "is_closed": false
    },
    {
        "day": "Friday",
        "open_time": "8:00 am",
        "close_time": "6:00 pm",
        "is_closed": false
    },
    {
        "day": "Saturday",
        "open_time": "8:00 am",
        "close_time": "6:00 pm",
        "is_closed": false
    },
    {
        "day": "Sunday",
        "is_closed": true
    },
]
```

### pharmacy_details
Returns
```js
{
    "name":"Pharmasolve Test Pharmacy",
    "address":"123 Street Name",
    "phone_number":"021 234 5678",
    "email":"test@pharmacy.com",
}
```

### keywords, number_whitelist
Returns
```js
['Prescriptions', 'Medicines', 'Doctor'] // an array of strings
```

### services
Returns
```js
[
	{
		name: "service_1",
		is_enabled: true,
		keywords: ["keyword_1","keyword_2"]
	},
	{
		name: "service_2",
		is_enabled: false,
		keywords: ["keyword_1","keyword_2"]
	}
]
```

## `/api/clinics/options`
METHOD: POST
AUTH: Bearer Token

Used to change clinic settings. All settings will take the object:
BODY:
```js
{
    "setting": "greeting", // setting name
    "option": ... // options for setting
}
```
Some settings have specific structure requirements for "option".

### greeting, read_medicines, location_instructions, holiday_hours
```js
{
    "setting": "greeting", // setting name
    "option": "Hi, this is chloe..." // any string
}
```
#### Notes:
- To disable or clear a setting, set "option" to null
- For read_medicines, there are 3 accepted options
    - 'Always Read'
    - 'Only Read After Pin'
    - 'Never Read'

### opening_hours
```js
{
    "setting": "opening_hours",
    "option": [
        {
            "day": "Monday",
            "open_time": "8:00 am", // optional if is_closed is true
            "close_time": "6:00 pm", // optional if is_closed is true
            "is_closed": false
        },
        {
            "day": "Tuesday",
            "open_time": "8:00 am", // optional if is_closed is true
            "close_time": "6:00 pm", // optional if is_closed is true
            "is_closed": false
        },
        {
            "day": "Wednesday",
            "open_time": "8:00 am", // optional if is_closed is true
            "close_time": "6:00 pm", // optional if is_closed is true
            "is_closed": false
        },
        {
            "day": "Thursday",
            "open_time": "8:00 am", // optional if is_closed is true
            "close_time": "6:00 pm", // optional if is_closed is true
            "is_closed": false
        },
        {
            "day": "Friday",
            "open_time": "8:00 am", // optional if is_closed is true
            "close_time": "6:00 pm", // optional if is_closed is true
            "is_closed": false
        },
        {
            "day": "Saturday",
            "open_time": "8:00 am", // optional if is_closed is true
            "close_time": "6:00 pm", // optional if is_closed is true
            "is_closed": false
        },
        {
            "day": "Sunday",
            "is_closed": true
        },
    ]
}
```

### pharmacy_details
```js
{
    "setting": "pharmacy_details",
    "option": {
        "name":"TWC Test Pharmacy",
        "address":"123 Street Name",
        "phone_number":"021 234 5678",
        "email":"test@pharmacy.com",
    }
}
```

### keywords, number_whitelist
```js
{
    "setting": "keywords", // or number_whitelist
    "option": [ "Doctor", "Asthma", "Prescribed" ] // array of strings containing keywords, whitelist numbers, etc.
}
```
#### Notes:
- Anything in the database that is not in the options array will be removed.
- Anything in the options array that is not in the database will be added.

### services
```js
{
    "setting": "services",
    "option": [
	    {
		    name: "service_1",
		    is_enabled: true,
		    keywords: ["keyword_1","keyword_2"]
	    },
	    {
		    name: "service_2",
		    is_enabled: false,
		    keywords: ["keyword_1","keyword_2"]
	    }
    ]
}
```

#### Notes:
- The database will be updated based on "option" e.g. if a flow is in the database but missing from "option" it will be removed from the database. The same applies for keywords.