NAV
shell

Overview

This describes the resources that make up the official Dentally API. The Dentally API is organized around REST. JSON will be returned from all responses from the API, including errors. If you have any problems or requests please contact support

API Endpoints


Production - https://api.dental.ly
Sandbox    - https://api.sandbox.dental.ly

Join the Developer Program

To join the Dentally Developer Program simply contact support who will be happy to get you setup with an account.

Versioning

By default, all requests receive the v1 version of the API. We encourage you to explicitly request the version by specifying it in the URL for example

https://api.dental.ly/v1/user

The version number is however optional and if it is missing you will simply receive the lastest version of the API.

https://api.dental.ly/user

Pagination

EXAMPLE PAGINATION

https://api.dental.ly/patients?page=2&per_page=50

Requests that return multiple items will be paginated to 25 items by default. You can specify further pages with the page parameter. For most resources, you can also set a custom page size, up to 100, with the per_page parameter.

EXAMPLE ORDERING

https://api.dental.ly/appointments?sort_by=id&sort_direction=desc



Ordering Resources

Most resources can also be ordered when listing multiple items. To order a resource, pass in the parameter sort_by and the name of the attribute you wish to order by. In addition, you can specify the direction you’d like to sort the attributes by including the parameter sort_direction. The available options for sort_direction are asc and desc

Metadata

EXAMPLE METADATA ATTRIBUTE

  "metadata": {
    "my_id": "ABC123"
  }

Some updatable Dentally objects - including Patients and Appointments - have a metadata parameter. You can use this parameter to attach key-value data to these Dentally objects. Metadata is useful for storing additional, structured information on an object. For example, you could store your unique ID and corresponding reference from your integration on a Dentally Patient object.

Metadata is not used by the Dentally app and won’t be seen by Dentally users unless you choose to show it to them.

Note: You can have up to 3 keys, with key names up to 40 characters long and values up to 500 characters long.

Cross Origin Resource Sharing

The API supports Cross Origin Resource Sharing (CORS) for AJAX requests from any origin.

EXAMPLE HEADERS

curl -i https://api.dental.ly -H "Origin: https://example.com"

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Headers: X-Requested-With, X-Prototype-Version, Content-Type, Authorization
Access-Control-Expose-Headers: ETag, X-OAuth-Scopes
X-OAuth-Scopes: user:read patient:read patient:update
ETag: "882411ad20c998d0e95b40d74af9b942"

User Agent Required

EXAMPLE 403 RESPONSE

{
  "error": {
    "type": "invalid_request_error",
    "message": "Request forbidden by administrative rules. Please make sure your request has a User-Agent header.",
    "documentation_url": "https://developer.dentally.co"
  }
}

All api requests must include a valid User-Agent header. Requests without a User-Agent header will be rejected. We request that you put your application name and version for the User-Agent header value.

Here’s an example:

User-Agent: Awesome-Dental-App v1

If you don’t include a valid User-Agent header you’ll receive a 403 Forbidden response.

Authentication via OAuth

The Dentally API uses OAuth2 for authentication. OAuth2 is a protocol that lets external apps request authorization to private details in a practice’s Dentally account without getting their password.

All developers need to register their application before getting started. A registered OAuth application is assigned a unique Client ID and Client Secret. The Client Secret should not be shared.

Create an Application

To create an application that has access to the Dentally API, login to Dentally and select Settings > Developer > Apps

Request Authorization

DEFINITION

GET https://api.dental.ly/oauth/authorize

EXAMPLE PARAMETERS

  {
    "client_id": "f4cdfd450cc1139fb71d8dbf1342fb512e5e9ca507be6a79cf454fbe3a75fd73",
    "redirect_uri": "https://example.com/callback",
    "scope": "appointment patient:read patient:update user:read",
    "response_type": "code",
    "state": "914e62ad35e7aa8a14f46bf8aff9194b24b7f6d7c5a434a7"
  }

Parameters

client_id:
string, required
The client ID you received from Dentally when you registered your application
redirect_uri:
string, required
The URL in your app where users will be sent after authorization
response_type:
string, required
This must always be set to code
scope:
string, required
A list of scopes seperated by a single space
state:
string, optional
An unguessable random string. It is used to protect against cross-site request forgery attacks

Get a Token

If the user accepts your request, Dentally redirects back to your site with a temporary code in a code parameter as well as the state you provided in the previous step in a state parameter. If the states don’t match, the request has been created by a third party and the process should be aborted. You can echange this temporary code for a token which will allow access to the API. Temporary codes are only valid for 10 minutes and API tokens are valid for a rolling 2 week period. If you don’t use your access token for a period longer than 2 weeks then it will automatically expire and you will have to request a new one.

DEFINITION

POST https://api.dental.ly/oauth/token

EXAMPLE RESPONSE

  {
    "access_token": "b3b2c56773ee72a90ab72ed4eb5a84edd48775380b81ab644f68441fdccceced",
    "token_type": "bearer"
  }

Parameters

client_id:
string, required
The client ID you received from Dentally when you registered your application.
client_secret:
string, required
The client secret you received from Dentally when you registered your application.
redirect_uri:
string, required
The URL in your app where users will be sent after authorization.
code:
string, required
The code you received when you requested authorization
grant_type:
string, required
This must always be set to authorization_code.

Use the Token

The access token allows you to make requests to the API on a behalf of a user.

GET https://api.dental.ly/user?access_token=...

The token can be passed as query param as shown above, however a cleaner approach is to include it in the Authorization header.

Authorization: Bearer ACCESS_TOKEN

Other Authentication Methods

While the API provides additional methods for authentication, we strongly recommend using OAuth for production applications. The other methods provided are intended to be used for scripts or testing (i.e., cases where full OAuth would be overkill).

Generate a Token

API tokens can also be generated in the from the developer dashboard with Dentally. To generate an access token, go to Settings > Developer > Tokens and select “Generate new token”. Here you’ll be able to select the scopes for the token and create it. Make sure to take a copy of your token after doing so as you won’t be able to see it again once you leave the page.

You should treat this token as if it were your password and keep it secure at all times. You can revoke your token at any point through the Developer Dashboard.

Use the Token

The access token allows you to make requests to the API on a behalf of a user.

GET https://api.dental.ly/user?access_token=...

The token can be passed as query param as shown above, however a cleaner approach is to include it in the Authorization header.

Authorization: Bearer ACCESS_TOKEN

Accounts

The account object

Accounts belong to patients and each patient in Dentally has their own account

EXAMPLE RESPONSE

{
  "account": {
    "id": 10,
    "current_balance": "200.0",
    "opening_balance": "10.0",
    "patient_id": 16,
    "patient_name": "Sergio Aguero",
    "planned_nhs_treatment_value": "50.0",
    "planned_private_treatment_value": "40.0"
  }
}

ATTRIBUTES

id:
integer
The ID of the account
current_balance:
string
The current balance of the account
opening_balance:
string
The opening balance for the account
patient_id:
integer
The ID of the patient the account belongs to
patient_name:
string
The first and last name of the patient the account belongs to
planned_nhs_treatment_value:
string
The total value of planned nhs treatment associated to the account
planned_private_treatment_value:
string
The total value of planned private treatment associated to the account

Get a single account

Retrives the details of an account

DEFINITION

GET https://api.dental.ly/v1/accounts/{ACCOUNT_ID}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/accounts/10

Parameters

id: required

Returns

The existing account object

EXAMPLE RESPONSE

{
  "account": {
    "id": 10,
    "current_balance": "200.0",
    "opening_balance": "10.0",
    "patient_id": 16,
    "patient_name": "Sergio Aguero",
    "planned_nhs_treatment_value": "50.0",
    "planned_private_treatment_value": "40.0"
  }
}

List all accounts

Returns a list of accounts.

DEFINITION

GET https://api.dental.ly/v1/accounts?{state, patient_id}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/accounts?state=credit

Parameters

state:
string, optional
You can filter by the state of the account wither it is in credit OR debit
patient_id:
string, optional
The ID of the patient that the account is assigned to

EXAMPLE RESPONSE:

{
  "accounts": [
    {
      "id": 10,
      "current_balance": "200.0",
      "opening_balance": "10.0",
      "patient_id": 16,
      "patient_name": "Sergio Aguero",
      "planned_nhs_treatment_value": "50.0",
      "planned_private_treatment_value": "40.0"
    },
    {...},
    {...}
  ],
  "meta": {
    "total": 3,
    "total_nhs": "200.00",
    "total_private": "400.00",
    "current_page": 1,
    "total_balance": "854.04"
  }
}

Returns

Returns a list of accounts that match the query. The response includes a metadata object which contains the page number, the total number of accounts, the total value of planned nhs treatments, the total value of planned private treatments and the total balance.

Appointments

The appointment object

Appointments belong to a practice and can be used for patient appointments, lunch breaks etc.

EXAMPLE RESPONSE

{
  "appointment": {
    "id": 2,
    "arrived_at": null,
    "cancelled_at": null,
    "completed_at": null,
    "confirmed_at": null,
    "did_not_attend_at": null,
    "duration": 15,
    "finish_time": "2013-11-05T09:40:00.000+00:00",
    "in_surgery_at": null,
    "metadata": {
    },
    "notes": "",
    "patient_name": "Harrison Daniel",
    "patient_id": 1001,
    "patient_image_url": "https://www.gravatar.com/avatar/b8a70ced4a175b0306a7cfb397ed714d.jpg?&r=pg&d=identicon&s=190",
    "payment_plan_id": 1,
    "pending_at": "2013-11-05T16:09:06.000+00:00",
    "practitioner_id": 1,
    "reason": "Exam",
    "start_time": "2013-11-05T09:25:00.000+00:00",
    "state": "Pending",
    "treatment_description": null,
    "user_id": 1
  }
}

ATTRIBUTES

id:
integer
The ID of the appointment
arrived_at:
datetime
When the appointment state was set to Arrived
cancelled_at:
datetime
When the appointment state was set to Cancelled
completed_at:
datetime
When the appointment state was set to Completed
confirmed_at:
datetime
When the appointment state was set to Confirmed
did_not_attend_at:
datetime
When the appointment state was set to Did not attend
duration:
integer
The length of the appointment in minutes
finish_time:
datetime
The date and time the appointment was set to finish
in_surgery_at:
datetime
When the appointment state was set to In surgery
metadata:
hash
A set of key/value pairs that you can attach to an appointment. It can be useful for storing additional information about the appointment in a structured format.
notes:
string
Any notes that were added to the appointment
patient_name:
string
The name of the patient the appointment is for
patient_id:
integer
The ID of the patient the appointment is for
patient_image_url:
string
The address for the image associated to the patient the appointment is for
payment_plan_id:
integer
The ID of the payment plan the patient belongs to
pending_at:
string
When the appointment state was set to Pending
practitioner_id:
integer
The ID of the practitioner assigned to the appointment
reason:
string
The reason for the appointment. Will be one of Exam, Scale & Polish, Exam + Scale & Polish, Continuing Treatment, Emergency, Review or Other
start_time:
datetime
The date and time the appointment was set to start
state:
string
The current state of the appointment. This can be Pending, Confirmed, Arrived, In surgery, Completed, Cancelled or Did not attend
treatment_description:
string
A short summary of treatment performed at that appointment
user_id:
integer
The ID of the user who created the appointment

Create an appointment

Creates a new appointment

DEFINITION

POST https://api.dental.ly/v1/appointments

EXAMPLE REQUEST

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --data-binary '{
  "appointment": {
    "start_time": "2015-01-02T13:00:00.000Z",
    "finish_time": "2015-01-02T13:10:00.000Z",
    "patient_id": 1,
    "practitioner_id": 1,
    "reason": "Exam"
  }
}' \
https://api.dental.ly/v1/appointments

Parameters

Parameters must be wrapped by an appointment object

start_time:
datetime, required
The start time of the appointment
finish_time:
datetime, required
The finish time of the appointment
practitioner_id:
integer, required
The ID of the practitioner
reason:
string, required
The reason for the appointment Must be one of Exam, Scale & Polish, Exam + Scale & Polish, Continuing Treatment, Emergency, Review or Other
patient_id:
integer, optional
The ID of the patient
state:
string, optional
The state of the appointment. Must be one of Pending, Confirmed, Arrived, In surgery, Completed, Cancelled or Did not attend. Defaults to Pending
notes:
string, optional
Notes specific to the appointment
metadata:
hash, optional
A set of key/value pairs that you can attach to an appointment. It can be useful for storing additional information about the appointment in a structured format.
force_changes:
boolean, optional
Setting this to true suppresses any double booking errors and allow the appointment to be double booked

EXAMPLE RESPONSE

{
  "appointment": {
    "id": 14493,
    "arrived_at": null,
    "cancelled_at": null,
    "completed_at": null,
    "confirmed_at": null,
    "did_not_attend_at": null,
    "duration": 10,
    "finish_time": "2015-01-02T13:10:00.000+00:00",
    "in_surgery_at": null,
    "metadata": {
    },
    "notes": null,
    "patient_name": "Liza Stafford",
    "patient_id": 1,
    "patient_image_url": "https://www.gravatar.com/avatar/d80c726c2a3a8f426acaa06e16b05b09.jpg?&r=pg&d=identicon&s=190",
    "payment_plan_id": 1,
    "pending_at": "2015-01-02T13:42:14.424+00:00",
    "practitioner_id": 1,
    "reason": "Exam",
    "start_time": "2015-01-02T13:00:00.000+00:00",
    "state": "Pending",
    "treatment_description": null,
    "user_id": 1
  }
}

Returns

The newly created appointment object

Get a single appointment

Retrives the details of an existing appointment

DEFINITION

GET https://api.dental.ly/v1/appointments/{APPOINTMENT_ID}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/appointments/14493

Parameters

id: required

EXAMPLE RESPONSE

{
  "appointment": {
    "id": 14493,
    "arrived_at": null,
    "cancelled_at": null,
    "completed_at": null,
    "confirmed_at": null,
    "did_not_attend_at": null,
    "duration": 10,
    "finish_time": "2015-01-02T13:10:00.000+00:00",
    "in_surgery_at": null,
    "metadata": {
    },
    "notes": null,
    "patient_name": "Liza Stafford",
    "patient_id": 1,
    "patient_image_url": "https://www.gravatar.com/avatar/d80c726c2a3a8f426acaa06e16b05b09.jpg?&r=pg&d=identicon&s=190",
    "payment_plan_id": 1,
    "pending_at": "2015-01-02T13:42:14.424+00:00",
    "practitioner_id": 1,
    "reason": "Exam",
    "start_time": "2015-01-02T13:00:00.000+00:00",
    "state": "Pending",
    "treatment_description": null,
    "user_id": 1
  }
}

Returns

The existing appointment object

Edit an appointment

Updates an existing appointment. Updating the appointment state will automatically update the corresponding timestamp.

DEFINITION

PUT/PATCH https://api.dental.ly/v1/appointments/{APPOINTMENT_ID}

EXAMPLE REQUEST

curl --include \
     --request PUT \
     --header "Content-Type: application/json" \
     --data-binary '{
  "appointment": {
    "finish_time": "2015-01-02T13:15:00.000Z"
  }
}' \
https://api.dental.ly/v1/appointments/14493

Parameters

Parameters must be wrapped by an appointment object

start_time:
datetime, optional
The start time of the appointment
finish_time:
datetime, optional
The finish time of the appointment
practitioner_id:
integer, optional
The ID of the practitioner
reason:
string, optional
The reason for the appointment. Must be one of Exam, Scale & Polish, Exam + Scale & Polish, Continuing Treatment, Emergency, Review or Other
patient_id:
integer, optional
The ID of the patient
state:
string, optional
The state of the appointment. Must be one of Pending, Confirmed, Arrived, In surgery, Completed, Cancelled or Did not attend. Defaults to Pending
metadata:
hash, optional
A set of key/value pairs that you can attach to an appointment. It can be useful for storing additional information about the appointment in a structured format.
notes:
string, optional
Notes specific to the appointment
force_changes:
boolean, optional
Setting this to true suppresses any double booking errors and allow the appointment to be double booked

EXAMPLE RESPONSE

{
  "appointment": {
    "id": 14493,
    "arrived_at": null,
    "cancelled_at": null,
    "completed_at": null,
    "confirmed_at": null,
    "did_not_attend_at": null,
    "duration": 15,
    "finish_time": "2015-01-02T13:15:00.000+00:00",
    "in_surgery_at": null,
    "metadata": {
    },
    "notes": null,
    "patient_name": "Liza Stafford",
    "patient_id": 1,
    "patient_image_url": "https://www.gravatar.com/avatar/d80c726c2a3a8f426acaa06e16b05b09.jpg?&r=pg&d=identicon&s=190",
    "payment_plan_id": 1,
    "pending_at": "2015-01-02T13:42:14.424+00:00",
    "practitioner_id": 1,
    "reason": "Exam",
    "start_time": "2015-01-02T13:00:00.000+00:00",
    "state": "Pending",
    "treatment_description": null,
    "user_id": 1
  }
}

Returns

The updated appointment object

Delete an appointment

Deletes an appointment. This should only be used when you want to remove an appointment. To cancel an appointment simply set the state of the appointment to Cancelled instead

DEFINITION

DELETE https://api.dental.ly/v1/appointments/{APPOINTMENT_ID}

EXAMPLE REQUEST

curl --include \
     --request DELETE \
https://api.dental.ly/v1/appointments/14493

Parameters

id: required

Returns

Returns a 204 response

List all appointments

DEFINITION

GET https://api.dental.ly/v1/appointments?{on,before,after,practitioner_id,patient_id,state}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/appointments?on=2015-01-02

EXAMPLE RESPONSE:

{
  "appointments": [
    {
      "id": 14493,
      "arrived_at": null,
      "cancelled_at": null,
      "completed_at": null,
      "confirmed_at": null,
      "did_not_attend_at": null,
      "duration": 15,
      "finish_time": "2015-01-02T13:15:00.000+00:00",
      "in_surgery_at": null,
      "metadata": {
      },
      "notes": null,
      "patient_name": "Liza Stafford",
      "patient_id": 1,
      "patient_image_url": "https://www.gravatar.com/avatar/d80c726c2a3a8f426acaa06e16b05b09.jpg?&r=pg&d=identicon&s=190",
      "payment_plan_id": 1,
      "pending_at": "2015-01-02T13:42:14.424+00:00",
      "practitioner_id": 1,
      "reason": "Exam",
      "start_time": "2015-01-02T13:00:00.000+00:00",
      "state": "Pending",
      "treatment_description": null,
      "user_id": 1
    },
    {...},
    {...}
  ],
  "meta": {
    "total": 3,
    "page": 1
  }
}

Returns a list of existing appointments

Parameters

Parameters are not mutually exclusive and can be combined to build up complex queries

on:
datetime, optional
On a date
before:
datetime, optional
Before a date
after:
datetime, optional
After a date
practitioner_id:
string, optional
With a practitioner
patient_id:
string, optional
With a patient
state:
string, optional
With a state
cancelled:
boolean, optional
Set to true to include cancelled appointments. Defaults to false

Returns

Returns a list of matching appointments. The response includes a metadata object which contains the page number that was returned as well as the total number of matching appointments. The appointments are returned in the order of their start time

Appointment availability

DEFINITION

GET https://api.dental.ly/v1/appointments/availability?{start_time,finish_time,duration,practitioner_ids}

EXAMPLE REQUEST

curl "https://api.dental.ly/v1/appointments/availability?practitioner_ids%5B%5D=1&duration=5&start_time=2015-01-07T12:00:11+00:00&finish_time=2015-02-06T12:00:11+00:00"

EXAMPLE RESPONSE:

{
  "availability": [
    {
      "start_time": "2015-01-07T12:00:00.000+00:00",
      "finish_time": "2015-01-07T14:20:00.000+00:00",
      "available_duration": 140
    },
    {
      "start_time": "2015-01-07T14:40:00.000+00:00",
      "finish_time": "2015-01-07T17:00:00.000+00:00",
      "available_duration": 140
    },
    {...}
  ],
  "meta": {
    "page": 1
  }
}

Returns a list of available time slots

Parameters

start_time:
datetime, required
A time to start searching from. Must be in the future
finish_time:
datetime, required
A time to search until. Must be in the future & after the start time
practitioner_ids:
array, required
An array of integers containing the IDs of the practitioners
duration:
integer, optional
The minimum duration required in minutes. If not supplied then this falls back to the practice’s minimum appointment duration (usually 5 minutes)
page:
integer, optional
The page to be returned
per_page:
integer, optional
The number of items to be returned per page (maximum is 20)

Returns

Returns a list of available time slots matching the requested criteria

start_time:
datetime
The start of the available period
finish_time:
datetime
The end of the available period
available_duration:
integer
The duration of the available period in minutes

Patients

The patient object

A patient belongs to a practice

EXAMPLE RESPONSE

{
  "patient": {
    "id": 1,
    "account_id": 1,
    "active": true,
    "address_line_1": "25.5 Coda Studios",
    "address_line_2": "Munster Road",
    "county": "London",
    "created_at": "2015-01-01T12:00:00.000+00:00",
    "custom_field_1": "92837484",
    "custom_field_2": null,
    "date_of_birth": "1988-06-02",
    "dentist_id": 1,
    "dentist_recall_date": "2016-01-09",
    "dentist_recall_interval": 6,
    "doctor_id": 1,
    "email_address": "[email protected]",
    "ethnicity": "16",
    "first_name": "Sergio",
    "gender": true,
    "home_phone": "02023456789",
    "hygienist_id": 2,
    "hygienist_recall_date": "2016-07-09",
    "hygienist_recall_interval": 12,
    "image_url": "https://www.gravatar.com/avatar/1c9e3735c970be65be56baa5db0edf83.jpg?&r=pg&d=identicon&s=190",
    "last_name": "Aguero",
    "legacy_id": "0000000010",
    "medical_alert": false,
    "medical_alert_text": null,
    "metadata": {
    },
    "middle_name": "Kun",
    "mobile_phone": "07123456789",
    "nhs_number": "0123456789",
    "ni_number": null,
    "occupation": "Footballer",
    "payment_plan_id": 2,
    "postcode": "FO07 8AL",
    "preferred_name": null,
    "preferred_phone_number": 3,
    "recall_method": "Letter",
    "title": "Mr",
    "town": "London",
    "updated_at": "2016-01-26T11:27:43.516+00:00",
    "use_email": false,
    "use_sms": true,
    "work_phone": "01234567890"
  }
}

ATTRIBUTES

id:
integer
The patient’s ID
account_id:
integer
The patient’s account ID
active:
boolean
If the patient is active true or has been archived false
address_line_1:
string
The first line of the patient’s address
address_line_2:
string
The second line of the patient’s address
county:
string
The county the patient resides
created_at:
datetime
The time and date the patient’s record was created
custom_field_1:
string
A data field a practice can use to store extra info about patients. Label is listed on the practice under custom_patient_field_label_1
custom_field_2:
string
A data field a practice can use to store extra info about patients. Label is listed on the practice under custom_patient_field_label_2
date_of_birth:
date
The patient’s date of birth
dentist_id:
integer
The practitioner ID of the patient’s preferred dentist
dentist_recall_date:
date
The date the patient is next due for a dental exam
dentist_recall_interval:
integer
The number of months between dental exams. Must be between 0 & 24
doctor_id:
integer
The ID of the patient’s doctor
email_address:
string
The patients email address
ethnicity:
string
The ethnicity code of the patient. Must be one of the codes listed here
first_name:
string
The patient’s first name
gender:
boolean
The patient’s gender (true for male, false for female)
home_phone:
string
The patient’s home phone number
hygienist_id:
integer
The practitioner ID of the patient’s preferred hygienist
hygienist_recall_date:
date
The date the patient is next due for a hygiene exam
hygienist_recall_interval:
integer
The number of months between hygiene exams. Must be between 0 & 24
image_url:
string
URL of the patient’s profile image
last_name:
string
The patient’s last name
legacy_id:
string
The patient’s ID on a previous or different system
medical_alert:
boolean
Set to true if the patient has a medical condition. Default false
medical_alert_text:
string
A summary of the patient’s medical condition
metadata:
hash
A set of key/value pairs that you can attach to a patient. It can be useful for storing additional information about the patient in a structured format.
middle_name:
string
The patient’s middle name.
mobile_phone:
string
The patient’s mobile phone number
nhs_number:
string
The patient’s NHS number
ni_number:
string
The patient’s national insurance number
occupation:
string
The patient’s occupation
payment_plan_id:
integer
The ID of the payment plan that the patient belongs to
postcode:
string
The patient’s postcode
preferred_name:
string
The patient’s preferred name
preferred_phone_number:
integer
The patient’s preferred contact number. 1 for home, 2 for work and 3 for mobile
recall_method:
string
The preferred method of contacting the patient when their recall is due. Must be Letter, SMS, Email or Phone. Default is Letter
title:
string
The patient’s title. It must be one of Mr, Mrs, Miss, Ms, Dr, Master, Prof, Hon, Rev, Sir, Lady, Lord, Earl, Judge or Dame
town:
string
The town the patient resides
updated_at:
datetime
The date and time the patients details were last updated
use_email:
boolean
If the patient wants to receive emails from the practice. Default true
use_sms:
boolean
If the patient wants to receive sms from the practice. Default true
work_phone:
string
The patient’s work phone number

Create a patient

Creates a new patient

DEFINITION

POST https://api.dental.ly/v1/patients

EXAMPLE REQUEST

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --data-binary '{
  "patient": {
    "title": "Mr",
    "first_name": "John",
    "last_name": "Smith",
    "date_of_birth": "1980-01-01",
    "gender": true,
    "ethnicity": "99",
    "address_line_1": "21 Oak Aveune",
    "postcode": "W1A 1AA",
    "payment_plan_id": 1
  }
}' \
https://api.dental.ly/v1/patients

Parameters

Parameters must be wrapped by a patient object

title:
string, required
The patient’s title. It must be one of Mr, Mrs, Miss, Ms, Dr, Master, Prof, Hon, Rev, Sir, Lady, Lord, Earl, Judge or Dame
first_name:
string, required
The patient’s first name
last_name:
string, required
The patient’s last name
date_of_birth:
date, required
The patient’s date of birth
gender:
boolean, required
The patient’s gender, true for male and false for female
ethnicity:
string, required
Must be one of the codes listed here
address_line_1:
string, required
The fist line of the patient’s address
postcode:
string, required
The patient’s postcode
payment_plan_id:
integer, required
The ID of the payment plan that the patient belongs to
active:
boolean, optional
If the patient is active. Default is true
address_line_2:
string, optional
The second line of the patient’s address
county:
string, optional
The patient’s address county
dentist_id:
integer, optional
The practitioner ID of the patient’s dentist
dentist_recall_date:
date, optional
The date the patient is next due for an exam
dentist_recall_interval:
integer, optional
The number of months between exams. Must be between 0 & 24
email_address:
string, optional
The patient’s email address
home_phone:
string, optional
The patient’s home phone number
hygienist_id:
integer, optional
The practitioner ID of the patient’s hygienist
hygienist_recall_date:
date, optional
The date the patient is next due for a scale and polish
hygienist_recall_interval:
integer, optional
The number of months between hygienist visits. Must be between 0 & 24
legacy_id:
string, optional
The patient’s ID on a previous or different system
medical_alert:
integer, optional
Set to true if the patient has a medical condition. Default false
medical_alert_text:
string, optional
A summary of the patient’s medical condition
metadata:
hash, optional
A set of key/value pairs that you can attach to a patient. It can be useful for storing additional information about the patient in a structured format.
middle_name:
string, optional
The patient’s middle name
mobile_phone:
string, optional
The patient’s mobile phone number
nhs_number:
string, optional
The patient’s NHS number
ni_number:
string, optional
The patient’s national insurance number
preferred_name:
string, optional
The patient’s nickname or preferred name
preferred_phone_number:
integer, optional
The phone number the patient prefers to be contacted on. 1 for home, 2 for work and 3 for mobile
recall_method:
string, optional
The preferred method of contacting the patient when their recall is due. Must be Letter, SMS, Email or Phone. Default is Letter
town:
string, optional
The patient’s address town
use_email:
boolean, optional
If the patient wants to receive emails from the practice. Default true
use_sms:
boolean, optional
If the patient wants to receive SMS from the practice. Default true

EXAMPLE RESPONSE

{
    "patient": {
        "id": 3,
        "account_id": 3,
        "active": true,
        "address_line_1": "21 Oak Aveune",
        "address_line_2": null,
        "county": null,
        "created_at": "2014-09-11T14:48:01.563+01:00",
        "date_of_birth": "1980-01-01",
        "dentist_id": null,
        "dentist_recall_date": null,
        "dentist_recall_interval": 0,
        "email_address": null,
        "ethnicity": "99",
        "first_name": "John",
        "gender": true,
        "home_phone": null,
        "hygienist_id": null,
        "hygienist_recall_date": null,
        "hygienist_recall_interval": 0,
        "image_url": "https://www.gravatar.com/avatar/fb830e28cd031264e371ab85563b37b0.jpg?&r=pg&d=identicon&s=190",
        "last_name": "Smith",
        "legacy_id": null,
        "medical_alert": false,
        "medical_alert_text": null,
        "metadata": {
        },
        "middle_name": null,
        "mobile_phone": null,
        "nhs_number": null,
        "ni_number": null,
        "occupation" null,
        "payment_plan_id": 1,
        "postcode": "W1A 1AA",
        "preferred_name": null,
        "preferred_phone_number": null,
        "recall_method": "Letter",
        "title": "Mr",
        "town": null,
        "updated_at": "2014-09-11T14:48:01.563+01:00",
        "use_email": true,
        "use_sms": true,
        "work_phone": null
    }
}

Returns

The newly created patient object

Get a single patient

Retrives the details of an existing patient

DEFINITION

GET https://api.dental.ly/v1/patients/{PATIENT_ID}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/patients/1

Parameters

id: required

Returns

The existing patient object

EXAMPLE RESPONSE

{
  "patient": {
    "id": 1,
    "account_id": 1,
    "active": true,
    "address_line_1": "135 New Crescent",
    "address_line_2": "Trlr 882",
    "county": "Breconshire",
    "created_at": "2013-11-04T03:07:33.954+00:00",
    "custom_field_1": "92837484",
    "custom_field_2": null,
    "date_of_birth": "1975-10-23",
    "dentist_id": null,
    "dentist_recall_date": null,
    "dentist_recall_interval": 12,
    "email_address": "[email protected]",
    "ethnicity": "07",
    "first_name": "Alesha",
    "gender": false,
    "home_phone": "013332511673",
    "hygienist_id": null,
    "hygienist_recall_date": null,
    "hygienist_recall_interval": 12,
    "image_url": "https://www.gravatar.com/avatar/7a37035f9ccdd683c05435e07c60ff90.jpg?&r=pg&d=identicon&s=190",
    "last_name": "Chaney",
    "legacy_id": null,
    "medical_alert": false,
    "medical_alert_text": null,
    "metadata": {
    },
    "middle_name": "Kiara",
    "mobile_phone": "07306743470",
    "nhs_number": "7474158055",
    "ni_number": null,
    "occupation" "Doctor",
    "payment_plan_id": 2,
    "postcode": "DG11 6JM",
    "preferred_name": null,
    "preferred_phone_number": 3,
    "recall_method": "Letter",
    "title": "Ms",
    "town": "Giffnock",
    "updated_at": "2013-11-04T03:07:33.954+00:00",
    "use_email": false,
    "use_sms": true,
    "work_phone": "020303132213"
  }
}

Edit a patient

Updates an existing patient

DEFINITION

PUT/PATCH https://api.dental.ly/v1/patients/{PATIENT_ID}

EXAMPLE REQUEST

curl --include \
     --request PUT \
     --header "Content-Type: application/json" \
     --data-binary '{
  "patient": {
    "first_name": "Frank"
  }
}' \
https://api.dental.ly/v1/patients/3

Parameters

Parameters must be wrapped by a patient object

title:
string, optional
The patient’s title. It must be one of Mr, Mrs, Miss, Ms, Dr, Master, Prof, Hon, Rev, Sir, Lady, Lord, Earl, Judge or Dame
first_name:
string, optional
The patient’s first name
last_name:
string, optional
The patient’s last name
date_of_birth:
date, optional
The patient’s date of birth
gender:
boolean, optional
The patient’s gender, true for male and false for female
ethnicity:
string, optional
Must be one of the codes listed here
address_line_1:
string, optional
The fist line of the patient’s address
postcode:
string, optional
The patient’s postcode
payment_plan_id:
integer, optional
The ID of the payment plan that the patient belongs to
active:
boolean, optional
If the patient is active. Default is true
address_line_2:
string, optional
The second line of the patient’s address
county:
string, optional
The patient’s address county
dentist_id:
integer, optional
The practitioner ID of the patient’s dentist
dentist_recall_date:
date, optional
The date the patient is next due for an exam
dentist_recall_interval:
integer, optional
The number of months between exams. Must be between 0 & 24
email_address:
string, optional
The patient’s email address
home_phone:
string, optional
The patient’s home phone number
hygienist_id:
integer, optional
The practitioner ID of the patient’s hygienist
hygienist_recall_date:
date, optional
The date the patient is next due for a scale and polish
hygienist_recall_interval:
integer, optional
The number of months between hygienist visits. Must be between 0 & 24
legacy_id:
string, optional
The patient’s ID on a previous or different system
medical_alert:
integer, optional
Set to true if the patient has a medical condition. Default false
medical_alert_text:
string, optional
A summary of the patient’s medical condition
metadata:
hash, optional
A set of key/value pairs that you can attach to a patient. It can be useful for storing additional information about the patient in a structured format.
middle_name:
string, optional
The patient’s middle name
mobile_phone:
string, optional
The patient’s mobile phone number
nhs_number:
string, optional
The patient’s NHS number
ni_number:
string, optional
The patient’s national insurance number
preferred_name:
string, optional
The patient’s nickname or preferred name
preferred_phone_number:
integer, optional
The phone number the patient prefers to be contacted on. 1 for home, 2 for work and 3 for mobile
recall_method:
string, optional
The preferred method of contacting the patient when their recall is due. Must be Letter, SMS, Email or Phone. Default is Letter
town:
string, optional
The patient’s address town
use_email:
boolean, optional
If the patient wants to receive emails from the practice. Default true
use_sms:
boolean, optional
If the patient wants to receive SMS from the practice. Default true

EXAMPLE RESPONSE

{
  "patient": {
    "id": 3,
    "account_id": 3,
    "active": true,
    "address_line_1": "21 Oak Aveune",
    "address_line_2": null,
    "county": null,
    "created_at": "2014-09-11T14:48:01.563+01:00",
    "custom_field_1": "92837484",
    "custom_field_2": null,
    "date_of_birth": "1980-01-01",
    "dentist_id": null,
    "dentist_recall_date": null,
    "dentist_recall_interval": 0,
    "email_address": null,
    "ethnicity": "99",
    "first_name": "Frank",
    "gender": true,
    "home_phone": null,
    "hygienist_id": null,
    "hygienist_recall_date": null,
    "hygienist_recall_interval": 0,
    "image_url": "https://www.gravatar.com/avatar/fb830e28cd031264e371ab85563b37b0.jpg?&r=pg&d=identicon&s=190",
    "last_name": "Smith",
    "legacy_id": null,
    "medical_alert": false,
    "medical_alert_text": null,
    "metadata": {
    },
    "middle_name": null,
    "mobile_phone": null,
    "nhs_number": null,
    "ni_number": null,
    "occupation" "Doctor",
    "payment_plan_id": 1,
    "postcode": "W1A 1AA",
    "preferred_name": null,
    "preferred_phone_number": null,
    "recall_method": "Letter",
    "title": "Mr",
    "town": null,
    "updated_at": "2014-09-11T14:48:01.563+01:00",
    "use_email": true,
    "use_sms": true,
    "work_phone": null
  }
}

Returns

The updated patient object

Delete a patient

This sets the patient’s active flag to false and can be undone by simply setting the active flag back to true

DEFINITION

DELETE https://api.dental.ly/v1/patients/{PATIENT_ID}

EXAMPLE REQUEST

curl --include \
     --request DELETE \
https://api.dental.ly/v1/patients/1

Parameters

id: required

Returns

Returns a 204 response

List all patients

Returns a list of existing patients

DEFINITION

GET https://api.dental.ly/v1/patients?query

EXAMPLE REQUEST

curl https://api.dental.ly/v1/patients?query=al

Parameters

query:
string, optional
A search query to filter patient records. This can be a combination of the patient’s first, middle and last names OR their postcode OR their date of birth OR their email address OR their home, work or mobile phone number (or part of). By default this list will only return active patients, to return only inactive patients include an asterisk * in the search query

EXAMPLE RESPONSE:

{
  "patients": [
    {
      "id": 1,
      "account_id": 1,
      "active": true,
      "address_line_1": "135 New Crescent",
      "address_line_2": "Trlr 882",
      "county": "Breconshire",
      "created_at": "2013-11-04T03:07:33.954+00:00",
      "custom_field_1": "92837484",
      "custom_field_2": null,
      "date_of_birth": "1975-10-23",
      "dentist_id": null,
      "dentist_recall_date": null,
      "dentist_recall_interval": 12,
      "email_address": "[email protected]",
      "ethnicity": "07",
      "first_name": "Alesha",
      "gender": false,
      "home_phone": "013332511673",
      "hygienist_id": null,
      "hygienist_recall_date": null,
      "hygienist_recall_interval": 12,
      "image_url": "https://www.gravatar.com/avatar/7a37035f9ccdd683c05435e07c60ff90.jpg?&r=pg&d=identicon&s=190",
      "last_name": "Chaney",
      "legacy_id": null,
      "medical_alert": false,
      "medical_alert_text": null,
      "metadata": {
      },
      "middle_name": "Kiara",
      "mobile_phone": "07306743470",
      "nhs_number": "7474158055",
      "ni_number": null,
      "occupation" "Doctor",
      "payment_plan_id": 2,
      "postcode": "DG11 6JM",
      "preferred_name": null,
      "preferred_phone_number": 3,
      "recall_method": "Letter",
      "title": "Ms",
      "town": "Giffnock",
      "updated_at": "2013-11-04T03:07:33.954+00:00",
      "use_email": false,
      "use_sms": true,
      "work_phone": "020303132213"
    },
    {...},
    {...}

  ],
  "meta": {
    "total": 3,
    "page": 1
  }
}

Returns

Returns a list of patients that match the query. The response includes a metadata object which contains the page number that was returned as well as the total number of patients that match the query. The patients are returned in the order that best matches the query

Payment Plans

The payment plan object

EXAMPLE RESPONSE

{
  "payment_plan": {
    "id": 1,
    "created_at": "2013-11-04T02:47:18.233+00:00",
    "colour": "#25B0E6",
    "name": "NHS"
  }
}

ATTRIBUTES

id:
integer
The ID of the payment plan
created_at:
string
The date and time the payment plan was created
colour:
string
The colour used to display the payment plan
name:
string
The name of the payment plan

Get a single payment plan

Retrives the details of an existing payment plan

DEFINITION

GET https://api.dental.ly/v1/payment_plans/{PAYMENT_PLAN_ID}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/payment_plans/1

Parameters

id: required

Returns

The existing payment plan object.

EXAMPLE RESPONSE

{
  "payment_plan": {
    "id": 1,
    "created_at": "2013-11-05T11:27:05.686+00:00",
    "colour": "#25B0E6",
    "name": "NHS"
  }
}

Edit a payment plan

Updates an existing payment plan

DEFINITION

PUT/PATCH https://api.dental.ly/v1/payment_plans/{PAYMENT_PLAN_ID}

EXAMPLE REQUEST

curl --include \
     --request PUT \
     --header "Content-Type: application/json" \
     --data-binary '{
  "payment_plan": {
    "colour": "#FFFFFF"
  }
}' \
https://api.dental.ly/v1/payment_plans/1

Parameters

Parameters must be wrapped by a payment_plan object

name:
string, optional
The name of the payment plan
colour:
string, optional
The payment plan’s colour. Must be in hexadecimal format

EXAMPLE RESPONSE

{
  "payment_plan": {
    "id": 1,
    "created_at": "2013-11-05T11:27:05.686+00:00",
    "colour": "#FFFFFF",
    "name": "NHS"
  }
}

Returns

The updated practitioner object with the associated user

List all payment plans

Returns a list of existing payment plans

DEFINITION

GET https://api.dental.ly/v1/payment_plans

EXAMPLE REQUEST

curl https://api.dental.ly/v1/payment_plans

Parameters

None.

EXAMPLE RESPONSE:

{
  "payment_plans": [
    {
      "id": 1,
      "created_at": "2013-11-05T11:27:05.686+00:00",
      "colour": "#25B0E6",
      "name": "NHS"
    },
    {...}
  ],
  "meta": {
    "total": 2,
    "page": 1
  }
}

Returns

Returns a list of payment plans ordered by ID

Payments

The payment object

A payment belongs to a patient and can be matched to an invoice or multiple invoices

EXAMPLE RESPONSE

{
  payment: {
    "id": 1,
    "account_id": 4511,
    "amount": "18.5",
    "amount_unexplained": "0.0",
    "dated_on": "2015-01-19",
    "deleted": false,
    "fully_explained": true,
    "method": "Debit Card",
    "patient_id": 5106,
    "practitioner_id": 1,
    "reference": "00001",
    "status": null,
    "transaction_number": "6932",
    "user_id": 271,
    "explanations": [
      {
        "amount": "18.5",
        "comments": null,
        "id": 57,
        "invoice_id": 51,
        "invoice_reference": "00051",
        "payment_id": 1,
        "payment_reference": "00001",
        "user_id": 253
      }
    ]
  }
}

ATTRIBUTES

id:
integer
The ID of the payment
account_id:
integer
The account ID the payment is associated to
amount:
string
The payment amount
amount_unexplained:
string
The payment amount that is still to be explained
dated_on:
date
The date assigned to the payment
deleted:
boolean
If the payment has been delete or not
fully_explained:
boolean
If the payment has been fully explained or not
method:
string
The payment method used to make the payment
patient_id:
integer
The ID of the patient the payment is assigned to
practitioner_id:
integer
The ID of the practitioner the payment is assigned to
reference:
string
The payment reference number generated for the payment
status:
string
The status of a Dentally Pay payment
transaction_number:
string
The transaction number added to the payment
user_id:
integer
The ID of the user who took the payment
explanations:
array
List of payment explanations
child attributes for explanation
id:
integer
The ID of the explanation
amount:
string
The amount that is being explained
comments:
string
A comment describing what the payment was for
invoice_id:
integer
The ID of the invoice the payment is explaining
invoice_reference:
string
The invoice reference number of the invoice the payment is explaining
payment_id:
integer
The ID of the payment that the explanation is explaining
payment_reference:
string
The payment reference number of the payment the explanition is explaining
user_id:
integer
The ID of the user who created the explanation

Create a payment

Creates a new payment

DEFINITION

POST https://api.dental.ly/v1/payments

EXAMPLE REQUEST

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --data-binary '{
  "payment": {
    "amount": "100.00",
    "dated_on": "2017-02-02",
    "method": "Cash",
    "patient_id": 1,
    "payment_plan_id": 1
  }
}' \
https://api.dental.ly/v1/payments

Parameters

Parameters must be wrapped by a payment object

amount:
string, required
The total value of the payment
dated_on:
date, required
The date the payment was made. This is the date that it will be applied to the patient’s account.
method:
string, required
The method of the payment. Must be one of Credit Card, Debit Card, American Express, Cash, Cheque, BACS, Finance or Other
patient_id:
integer, required
The ID of the patient the payment is associated with.
payment_plan_id:
integer, required
The ID of the payment plan the payment is associated with.
practitioner_id:
integer, optional
The ID of the practitioner the payment is associated with.
transaction_number:
string, optional
A transaction number which can be used to identify the payment with a third party system.

EXAMPLE RESPONSE

{
  "payment": {
    "id": 1,
    "account_id": 1,
    "amount": "100.0",
    "amount_unexplained": "100.0",
    "dated_on": "2017-02-02",
    "deleted": false,
    "fully_explained": false,
    "method": "Cash",
    "patient_id": 1,
    "practitioner_id": null,
    "reference": "00001",
    "status": null,
    "transaction_number": null,
    "user_id": 1,
    "explanations": []
  }
}

Returns

The newly created payment object

Get a single payment

Retrives the details of a payment

DEFINITION

GET https://api.dental.ly/v1/payments/{PAYMENT_ID}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/payments/1

Parameters

id: required

Returns

The existing payment object

EXAMPLE RESPONSE

{
  payment: {
    "id": 1,
    "account_id": 4511,
    "amount": "18.5",
    "amount_unexplained": "0.0",
    "dated_on": "2015-01-19",
    "deleted": false,
    "fully_explained": true,
    "method": "Debit Card",
    "patient_id": 5106,
    "practitioner_id": 1,
    "reference": "00001",
    "status": null,
    "transaction_number": "6932",
    "user_id": 271,
    "explanations": [
      {
        "amount": "18.5",
        "comments": null,
        "id": 57,
        "invoice_id": 51,
        "invoice_reference": "00051",
        "payment_id": 1,
        "payment_reference": "00001",
        "user_id": 253
      }
    ]
  }
}

Delete a payment

Deletes a payment. This should only be used when you want to remove a payment and any associated explanations.

DEFINITION

DELETE https://api.dental.ly/v1/payments/{PAYMENT_ID}

EXAMPLE REQUEST

curl --include \
     --request DELETE \
https://api.dental.ly/v1/payments/1

Parameters

id:
integer
required

Returns

Returns a 204 response

List all payments

Returns a list of payments

DEFINITION

GET https://api.dental.ly/v1/payments?{practitioner_id, payment_plan_id, dated_after, dated_before, patient_id}

EXAMPLE REQUEST

curl http://api.rails.dev:3000/payments?dated_after=2016-01-05

Parameters

practitioner_id:
string, optional
Payments assigned to a specific practitioner
payment_plan_id:
string, optional
Payments assigned to a specific payment plan
dated_after:
date, optional
After a date
dated_before:
date, optional
Before a date
patient_id:
string, optional
Payments belonging to a specific patient

EXAMPLE RESPONSE:

{
  "payments": [
    {
      "id": 1,
      "account_id": 4511,
      "amount": "18.5",
      "amount_unexplained": "0.0",
      "dated_on": "2015-01-19",
      "deleted": false,
      "fully_explained": true,
      "method": "Debit Card",
      "patient_id": 5106,
      "practitioner_id": 1,
      "reference": "00001",
      "status": null,
      "transaction_number": "6932",
      "user_id": 271,
      "explanations": [
        {
          "amount": "18.5",
          "comments": null,
          "id": 57,
          "invoice_id": 51,
          "invoice_reference": "00051",
          "payment_id": 1,
          "payment_reference": "00001",
          "user_id": 253
        }
      ]
    }
    ,
      {...},
      {...}
  ],
  "meta": {
    "current_page": 1,
    "total": 3,
    "total_amount": "854.04"
  }
}

Returns

Returns a list of payments that match the query. The response includes a metadata object which contains the page number, the total number of payments, the total value of planned nhs treatments, the total value of planned private treatments and the total balance.

Payment Explanations

The payment explanation object

A payment explanation is used to describe why the payment was made. Payment explanations must be associated with a payment and can optionally be associated with an invoice.

EXAMPLE RESPONSE

{
  "explanation": {
    "id": 1,
    "amount": "100",
    "comments": "Deposit for treatment",
    "invoice_id": null,
    "invoice_reference": null,
    "payment_id": 1,
    "payment_reference": "0001",
    "user_id": 1
  }
}

ATTRIBUTES

id:
integer
The ID of the explanation
amount:
string
The amount that is being explained
comments:
string
A comment describing what the payment was for
invoice_id:
integer
The ID of the invoice the payment is explaining
invoice_reference:
string
The invoice reference number of the invoice the payment is explaining
payment_id:
integer
The ID of the payment that the explanation is explaining
payment_reference:
string
The payment reference number of the payment the explanition is explaining
user_id:
integer
The ID of the user who created the explanation

Create a payment explanation

Creates a new payment explanation

DEFINITION

POST https://api.dental.ly/v1/payments/{PAYMENT_ID}/explanations/

EXAMPLE REQUEST

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --data-binary '{
  "explanation": {
    "amount": "100",
    "comments": "Deposit for treatment"
  }
}' \
https://api.dental.ly/v1/payments

Parameters

Parameters must be wrapped by a explanation object

amount:
string, required
The value of the payment that you would like to explain. This must be less than or equal to the total value of the payment
comments:
string, required
A comment describing what the payment was for

EXAMPLE RESPONSE

{
  "explanation": {
    "id": 1,
    "amount": "100",
    "comments": "Deposit for treatment",
    "invoice_id": null,
    "invoice_reference": null,
    "payment_id": 1,
    "payment_reference": "0001",
    "user_id": 1
  }
}

Returns

The newly created payment explanation object

Delete a payment explanation

Deletes a payment explanation. You can also delete all explanations associated with a payment by deleting the associated payment object.

DEFINITION

DELETE https://api.dental.ly/v1/payments/{PAYMENT_ID}/explanations/{PAYMENT_EXPLANATION_ID}

EXAMPLE REQUEST

curl --include \
     --request DELETE \
https://api.dental.ly/v1/payments/1/explanations/1

Parameters

payment_id:
integer
required
payment_explanation_id:
integer
required

Returns

Returns a 204 response

Practitioners

The practitioner object

A practitioner account belongs to a user

EXAMPLE RESPONSE

{
  "practitioner": {
    "id": 1,
    "active": true,
    "colour": "#6796f2",
    "gdc_number": null,
    "nhs_number": null,
    "user": {
      "id": 1,
      "created_at": "2013-11-04T02:47:17.380+00:00",
      "email": "[email protected]",
      "first_name": "Ross",
      "image_url": "https://www.gravatar.com/avatar/672a9f4da85d4b2026059973b84dd827.jpg?&r=pg&d=identicon&s=100",
      "last_login": "2016-01-26T10:24:07.961+00:00",
      "last_name": "Hepburn",
      "middle_name": null,
      "mobile_phone": "07123456789",
      "permission_level": 4,
      "role": "Dentist"
    }
  }
}

ATTRIBUTES

id:
integer
The ID of the practitioner
active:
boolean
If set to false the practitioner will be hidden in Dentally
colour:
string
The practitioner’s colour. Must be in hexadecimal format, e.g. #FFFFFF
gdc_number:
string
The practitioner’s GDC number
nhs_number:
string
The practitioner’s NHS number
user:
string
The practitioners user account
child attributes for user
id:
intger
description
created_at:
datetime
The date and time the user was created
email:
string
The user’s email address
first_name:
string
The user’s first name
image_url:
string
URL of the users’s profile image
last_login:
datetime
The date and time the user last logged in
last_name:
string
The user’s last name
middle_name:
string
The user’s middle name
mobile_phone:
string
The user’s mobile phone number
permission_level:
integer
The user’s permission level. Can range between 0 and 4. Further details on permission levels can be found here
role:
string
The user’s role. Must be one of Administrator, Dentist, Hygienist, Nurse, Practice Manager, Receptionist, Technician, Therapist

Get a single practitioner

Retrives the details of an existing practitioner with the associated user

DEFINITION

GET https://api.dental.ly/v1/practitioners/{PRACTITIONER_ID}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/practitioners/1

Parameters

id: required

Returns

The existing practitioner object

EXAMPLE RESPONSE

{
  "practitioner": {
    "id": 1,
    "active": true,
    "colour": "#9CCB3B",
    "gdc_number": null,
    "nhs_number": null,
    "user": {
      "id": 4,
      "created_at": "2013-11-05T11:26:52.904+00:00",
      "email": "[email protected]",
      "first_name": "Greg",
      "image_url": "https://www.gravatar.com/avatar/0242720e04226d4d190f9ffc15a2644b.jpg?&r=pg&d=identicon&s=100",
      "last_login": "2015-01-05T11:03:01.020+00:00",
      "last_name": "Hays",
      "middle_name": null,
      "mobile_phone": null,
      "permission_level": 4,
      "role": "Dentist"
    }
  }
}

Edit a practitioner

Updates an existing practitioner

DEFINITION

PUT/PATCH https://api.dental.ly/v1/practitioners/{PRACTITIONER_ID}

EXAMPLE REQUEST

curl --include \
     --request PUT \
     --header "Content-Type: application/json" \
     --data-binary '{
  "practitioner": {
    "gdc_number": "12345"
  }
}' \
https://api.dental.ly/v1/practitioners/1

Parameters

Parameters must be wrapped by a practitioner object

active:
boolean, optional
If set to false the practitioner will be hidden in Dentally
colour:
string, optional
The practitioner’s colour. Must be in hexadecimal format, e.g. #FFFFFF
gdc_number:
string, optional
The practitioner’s GDC number
nhs_number:
string, optional
The practitioner’s NHS number

EXAMPLE RESPONSE

{
  "practitioner": {
    "id": 1,
    "active": true,
    "colour": "#9CCB3B",
    "gdc_number": "12345",
    "nhs_number": null,
    "user": {
      "id": 4,
      "created_at": "2013-11-05T11:26:52.904+00:00",
      "email": "[email protected]",
      "first_name": "Greg",
      "image_url": "https://www.gravatar.com/avatar/0242720e04226d4d190f9ffc15a2644b.jpg?&r=pg&d=identicon&s=100",
      "last_login": "2015-01-05T11:03:01.020+00:00",
      "last_name": "Hays",
      "middle_name": null,
      "mobile_phone": null,
      "permission_level": 4,
      "role": "Dentist"
    }
  }
}

Returns

The updated practitioner object with the associated user.

List all practitioners

Returns a list of existing practitioners

DEFINITION

GET https://api.dental.ly/v1/practitioners

EXAMPLE REQUEST

curl https://api.dental.ly/v1/practitioners

Parameters

None

EXAMPLE RESPONSE:

{
  "practitioners": [
    {
      "id": 1,
      "active": true,
      "colour": "#9CCB3B",
      "gdc_number": null,
      "nhs_number": null,
      "user": {
        "id": 4,
        "created_at": "2013-11-05T11:26:52.904+00:00",
        "email": "[email protected]",
        "first_name": "Greg",
        "image_url": "https://www.gravatar.com/avatar/0242720e04226d4d190f9ffc15a2644b.jpg?&r=pg&d=identicon&s=100",
        "last_login": "2015-01-05T11:03:01.020+00:00",
        "last_name": "Hays",
        "middle_name": null,
        "mobile_phone": null,
        "permission_level": 4,
        "role": "Dentist"
      }
    },
    {...}
  ],
  "meta": {
    "total": 2,
    "page": 1
  }
}

Returns

Returns a list of practitioners ordered by ID

Users

The user object

A user belongs to a practice

EXAMPLE RESPONSE

{
  "user": {
    "id": 1,
    "created_at": "2013-11-04T02:47:17.380+00:00",
    "email": "[email protected]",
    "first_name": "Ross",
    "image_url": "https://www.gravatar.com/avatar/672a9f4da85d4b2026059973b84dd827.jpg?&r=pg&d=identicon&s=100",
    "last_login": "2016-01-26T10:24:07.961+00:00",
    "last_name": "Hepburn",
    "middle_name": null,
    "mobile_phone": "07123456789",
    "permission_level": 4,
    "role": "Dentist"
  }
}

ATTRIBUTES

id:
intger
The ID of the user
created_at:
datetime
The date and time the user was created
email:
string
The user’s email address
first_name:
string
The user’s first name
image_url:
string
URL of the users’s profile image
last_login:
datetime
The date and time the user last logged in
last_name:
string
The user’s last name
middle_name:
string
The user’s middle name
mobile_phone:
string
The user’s mobile phone number
permission_level:
integer
The user’s permission level. Can range between 0 and 4. Further details on permission levels can be found here
role:
string
The user’s role. Must be one of Administrator, Dentist, Hygienist, Nurse, Practice Manager, Receptionist, Technician or Therapist

Get the authenticated user

Retrives the details of the currently authenticated user

DEFINITION

GET https://api.dental.ly/v1/user

EXAMPLE REQUEST

curl https://api.dental.ly/v1/user

Parameters

None

EXAMPLE RESPONSE

{
  "user": {
    "id": 1,
    "created_at": "2015-01-01T12:02:52.402+00:00",
    "email": "[email protected]",
    "first_name": "Gregory",
    "image_url": "https://www.gravatar.com/avatar/0242720e04226d4d190f9ffc15a2644b.jpg?&r=pg&d=identicon&s=100",
    "last_login": "2015-01-02T18:16:50.235+00:00",
    "last_name": "Hays",
    "middle_name": null,
    "mobile_phone": null,
    "permission_level": 4,
    "role": "Dentist"
  }
}

Returns

A user object

Get a single user

Retrives the details of an existing user

DEFINITION

GET https://api.dental.ly/v1/users/{USER_ID}

EXAMPLE REQUEST

curl https://api.dental.ly/v1/users/1

Parameters

id: required

EXAMPLE RESPONSE

{
  "user": {
    "id": 1,
    "created_at": "2015-01-01T12:02:52.402+00:00",
    "email": "[email protected]",
    "first_name": "Gregory",
    "image_url": "https://www.gravatar.com/avatar/0242720e04226d4d190f9ffc15a2644b.jpg?&r=pg&d=identicon&s=100",
    "last_login": "2015-01-02T18:16:50.235+00:00",
    "last_name": "Hays",
    "middle_name": null,
    "mobile_phone": null,
    "permission_level": 4,
    "role": "Dentist"
  }
}

Returns

A user object

Edit a user

Updates an existing user

DEFINITION

PUT/PATCH https://api.dental.ly/v1/users/{PATIENT_ID}

EXAMPLE REQUEST

curl --include \
     --request PUT \
     --header "Content-Type: application/json" \
     --data-binary '{
  "user": {
    "first_name": "Greg"
  }
}' \
https://api.dental.ly/v1/users/1

Parameters

Parameters must be wrapped by a user object

email:
string, optional
The user’s email address
first_name:
string, optional
The user’s first name
middle_name:
string, optional
The user’s middle name
last_name:
string, optional
The user’s last name
mobile_phone:
string, optional
The user’s mobile phone number
role:
string, optional
The user’s role. Must be one of Administrator, Dentist, Hygienist, Nurse, Practice Manager, Receptionist, Technician and Therapist
permission_level:
interger, optional
The user’s permission level. Can range between 0 and 4. Further details on permission levels can be found here

EXAMPLE RESPONSE

{
  "user": {
    "id": 1,
    "created_at": "2015-01-01T12:02:52.402+00:00",
    "email": "[email protected]",
    "first_name": "Greg",
    "image_url": "https://www.gravatar.com/avatar/0242720e04226d4d190f9ffc15a2644b.jpg?&r=pg&d=identicon&s=100",
    "last_login": "2015-01-02T18:16:50.235+00:00",
    "last_name": "Hays",
    "middle_name": null,
    "mobile_phone": null,
    "permission_level": 4,
    "role": "Dentist"
  }
}

Returns

The updated user object

List all users

Returns a list of all users

DEFINITION

GET https://api.dental.ly/v1/users

EXAMPLE REQUEST

curl https://api.dental.ly/v1/users

Parameters

None

EXAMPLE RESPONSE:

{
  "users": [
    {
      "id": 1,
      "created_at": "2015-01-01T12:02:52.402+00:00",
      "email": "[email protected]",
      "first_name": "Greg",
      "image_url": "https://www.gravatar.com/avatar/0242720e04226d4d190f9ffc15a2644b.jpg?&r=pg&d=identicon&s=100",
      "last_login": "2015-01-02T18:16:50.235+00:00",
      "last_name": "Hays",
      "middle_name": null,
      "mobile_phone": null,
      "permission_level": 4,
      "role": "Dentist"
    },
    {...},
    {...}

  ],
  "meta": {
    "total": 3,
    "page": 1
  }
}

Returns

Returns a list of all users in your practice. The list is ordered by ID

Practice

The practice object

EXAMPLE RESPONSE

{
  "practice": {
    "address_line_1": "126 The Crescent",
    "address_line_2": "",
    "custom_patient_field_label_1": "Insurance Number",
    "custom_patient_field_label_2": null,
    "email_address": "[email protected]",
    "logo_url": "https://res.cloudinary.com/njtech/image/upload/v1399365577/uwwnz0g5wdm0tgr5byy3.png",
    "name": "Dentally Dental",
    "nhs": true,
    "patient_email_address": "[email protected]",
    "phone_number": "020134848228",
    "postcode": "W1A 1AA",
    "slug": "dentalpractice",
    "time_zone": "London",
    "town": "Pontyberem",
    "website": "dentalpractice.com"
  }
}

ATTRIBUTES

address_line_1:
string
The first line of the practice’s address
address_line_2:
string
The second line of the practice’s address
custom_patient_field_label_1:
string
The label for a data field a practice can use to store extra info about patients. Field is listed on the patient as custom_field_1
custom_patient_field_label_2:
string
The label for a data field a practice can use to store extra info about patients. Field is listed on the patient as custom_field_2
email_address:
string
The email address for the practice
logo_url:
string
The URL of the practice’s logo
name:
string
The name of the practice
nhs:
boolean
If the practice is NHS. Default false
patient_email_address:
string
The email address used to send emails to patients
phone_number:
string
The phone number for the practice
postcode:
string
The postcode for the practice
slug:
string
description
time_zone:
string
The practice timezone
town:
string
The town the practice resides
website:
string
The practices website address

Get the practice

Retrives the details of the currently authenticated user’s practice

DEFINITION

GET https://api.dental.ly/v1/practice

EXAMPLE REQUEST

curl https://api.dental.ly/v1/practice

Parameters

None

EXAMPLE RESPONSE

{
  "practice": {
    "address_line_1": "126 The Crescent",
    "address_line_2": "",
    "custom_patient_field_label_1": "Insurance Number",
    "custom_patient_field_label_2": null,
    "email_address": "[email protected]",
    "logo_url": "https://res.cloudinary.com/njtech/image/upload/v1399365577/uwwnz0g5wdm0tgr5byy3.png",
    "name": "Dentally Dental",
    "nhs": true,
    "patient_email_address": "[email protected]",
    "phone_number": "020134848228",
    "postcode": "W1A 1AA",
    "slug": "dentalpractice",
    "time_zone": "London",
    "town": "Pontyberem",
    "website": "dentalpractice.com"
  }
}

Returns

A practice object

Webhooks

Overview

EXAMPLE WEBHOOK

POST https://example.com/webhooks

User-Agent: Dentally-Webhook
Content-Type: application/json
X-Dentally-Signature: 63e0b2c79e8b73993777ce312d6b3ad421742d9a8f2657a3e3c14909c6578ab6

{
  "data": {
    "id": 2181,
    "arrived_at": null,
    "cancelled_at": null,
    "completed_at": null,
    "confirmed_at": null,
    "did_not_attend_at": null,
    "duration": 30,
    "finish_time": "2015-07-08 10:00:00 +0100",
    "in_surgery_at": null,
    "notes": null,
    "patient_name": "Carolina James",
    "patient_id": 1,
    "patient_image_url": "https://www.gravatar.com/avatar/207bbfd487c85ff34a2e7781f80c1305.jpg?&r=pg&d=identicon&s=190",
    "payment_plan_id": 1,
    "pending_at": "2015-07-01 12:00:00 +0100",
    "practitioner_id": 1,
    "reason": "Exam",
    "start_time": "2015-07-08 09:30:00 +0100",
    "state": "Pending",
    "treatment_description": null,
    "user_id": 1
  },
  "event": "appointment.created",
  "object": "appointment",
  "user": {
    "id": 1,
    "created_at": "2015-01-01T12:02:52.402+00:00",
    "email": "[email protected]",
    "first_name": "Gregory",
    "image_url": "https://www.gravatar.com/avatar/0242720e04226d4d190f9ffc15a2644b.jpg?&r=pg&d=identicon&s=100",
    "last_login": "2015-01-02T18:16:50.235+00:00",
    "last_name": "Hays",
    "middle_name": null,
    "mobile_phone": null,
    "permission_level": 4,
    "role": "Dentist"
  }
}

Webhooks notify you of new events in your Dentally account (e.g., when a new appointment has been created).

You can enable webhooks by creating a Webhook from your Dentally Developer Settings.

When an event occurs in your Dentally account, a webhook will be sent to every enabled webhook endpoint as a POST request, which contains details about the event as well as details about the user that triggered the event, if applicable.

There are a few other things to note when using webhooks:

Status codes

Your webhook handler should return a response with a 2xx status code, e.g. 200 OK, or 204 No Content. Returning any other error code will cause Dentally to retry the webhook.

Errors & Retries

In the event we fail to deliver the webhook, or you respond with a non 2xx status code, we will attempt to resend the webhook up to 10 times at increasing time intervals. If we fail to devliver more than 50 webhooks to your endpoint then the webhook will automatically be disabled. It can be renabled from your Developer Settings.

Signing Webhooks

We sign the body of the POST request with an HMAC SHA256 hex digest, using the secret of the webhook endpoint for which this webhook is being sent. The signature is sent in the header of the request:

EXAMPLE SIGNATURE

X-Dentally-Signature: 63e0b2c79e8b73993777ce312d6b3ad421742d9a8f2657a3e3c14909c6578ab6

You must check that the webhook has a valid signature before processing it. Here’s how you could do that in Ruby.

Scopes

Scopes let you specify exactly what type of access you need. Scopes limit access for OAuth tokens, they do not grant any additional permission beyond that which the user already has.

The requested scopes will be displayed to the user on the authorization form.

You should only request the scopes that are required for your application. Applications requesting unnecessary scopes may have their access tokens revoked.

You can find the current OAuth scopes in the X-OAuth-Scopes header.

$ curl -H "Authorization: Bearer ACCESS_TOKEN" https://api.dental.ly -I

HTTP/1.1 200 OK
X-OAuth-Scopes: user:read patient:read patient:update
Name Description
user All user & practitioner actions. This scope includes user:read and user:update
user:read Read user & practitioner data
user:update Update user & practitioner data
appointment All appointment actions. This scope includes appointment:read, appointment:create, appointment:update and appointment:delete
appointment:read View appointment data
appointment:create Create appointments
appointment:update Update appointments
appointment:delete Delete appointments
financials All financial actions. This scope includes financials:read, financials:create and financials:delete
financials:read Read account, payment and invoice data
financials:create Create payments and payment explanations.
financials:delete Delete payments and payment explanations.
patient All patient actions. This scope includes patient:read, patient:create, patient:update and patient:delete
patient:read View patient data
patient:create Create patients
patient:update Update patients
patient:delete Archive patients
practice:read View practice data

Errors

Dentally uses HTTP response codes to indicate the success or failure of the API request

EXAMPLE RESPONSE

{
  "error": {
    "type": "invalid_access_error",
    "message": "API access is not enabled for this user",
    "documentation_url": "https://developer.dentally.co"
  }
}

EXAMPLE RESPONSE

{
  "error": {
    "type": "invalid_request_error",
    "message": "The patient could not be saved",
    "params": {
      "first_name": [
        "seems to be missing"
      ]
    }
  }
}

Attributes

Attributes will be wrapped in an error object

type:
string
The type of error returned. This can be invalid_request_error or invalid_access_error
message:
string
A human readable message providing more details about the error. These can be displayed to your users
params:
hash, optional
The parameters the error(s) relate to and associated message(s). You can use this to display more detailed errors to your users

HTTP Response Codes

Code Reason
200 OK – Everything worked as expected
204 No Content – Everything worked as expected but we’re not returning any content
400 Bad Request – Often missing a required parameter
401 Unauthorized – Your API key is not valid
403 Forbidden – The user does not have access to the requested item
404 Not Found – The requested item could not be found
410 Gone – The requested resource has been removed
422 Unprocessable Entity – The requested item could not be processed. The reason will be included in the response
500 Internal Server Error – We had a problem with our server. Try again later or check our status page
503 Service Unavailable – We’re temporarially offline for maintanance. Please try again later

Rate Limits

The Dentally API is rate limited on a per user basis. Each user is allowed to make 3,600 requests per hour however the Appointment availability endpoint is restricted to 100 requests per hour.

You can check the returned HTTP headers of any API request to see your current rate limit status:

EXAMPLE HEADERS

curl -i https://api.dental.ly/users

HTTP/1.1 200 OK
X-RateLimit-Limit: 3600
X-RateLimit-Remaining: 3278
X-RateLimit-Reset: 1494590400
Header Name Description
X-RateLimit-Limit The maximum number of requests that the user is permitted to make per hour.
X-RateLimit-Remaining The number of requests remaining in the current rate limit window.
X-RateLimit-Reset The time at which the current rate limit window resets in UTC epoch seconds.

Once you go over the rate limit you will receive an error response.

EXAMPLE ERROR

HTTP/1.1 403 Forbidden
X-RateLimit-Limit: 3600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1494590400
{
  "error": {
    "type": "invalid_access_error",
    "message": "Rate limit exceeded"
  }
}

Checking your rate limit

DEFINITION

GET https://api.dental.ly/rate_limit

EXAMPLE RESPONSE

  {
    "resources": {
      "core": {
        "limit": 3600,
        "remaining": 3595,
        "reset": 1494590400
      },
      "appointment_availability": {
        "limit": 100,
        "remaining": 98,
        "reset": 1494590400
      }
    }
  }

You can check your current rate limit status at any point using the rate limit API. Accessing this endpoint does not count against your rate limit.

Data Formatting

Time zones / dates All timestamps are formatted as ISO8601 with timezone information. For endpoints that allow for a timestamp to be specified, we use that exact timestamp. These timestamps look something like 2017-02-03T13:14:15.123Z.

For endpoints that require dates, we expect a date string in the format YYYY-MM-DD, where an example would look like 2017-02-03.
Email addresses Must comply with RFC 2822 and RFC 3696

Changelog

API Changelog

Sign up here to be notified about changes to the Dentally API. We try and make changes as backwards compatible as possible however, occassionally, breaking changes may be required.

2017-02-03 Added metadata attributes to patients and appointments.
Payments and payment explanations can now be created and deleted.
2015-02-02 Added payments and accounts (read only)
2015-02-12 Added custom fields \ labels to the patient and practice objects