This is the official PracSuite API.
It follows standard REST conventions, so you can work with it using any HTTP client and any programming language that can send HTTP requests.
All responses are returned in JSON format.
All requests to the API must include two headers. Both are required for a request to be accepted.
x-api-keyThis is the vendor key issued by Smartsoft. It identifies your application as an approved integration partner. This key is managed by Smartsoft and does not change unless it is rotated by us.A-api-keyThis is the account-level key generated inside PracSuite by each clinic. It authorises access to that clinic’s data and can be created or revoked by the clinic at any time.
A request missing either header will be rejected.
Example
curl -X GET "https://api.pracsuite.com/v1/patient?page=1&page_size=50" \
-H "x-api-key: <vendor-api-key>" \
-H "A-api-key: <pracsuite-generated-api-key>"Anyone with these keys can access your clinic’s data, so store them in a safe place, don’t embed them in client-side code, and request to rotate them immediately if you believe they’ve been exposed.
Endpoints that return lists use pagination. By default, each response includes up to 50 items. You can request additional pages with the page parameter, and you may increase the page_size to a maximum of 100.
Each paginated response also includes a total_entries value so you know how many records are available.
Pagination details are provided in the links object. It’s best to use these links when navigating between pages rather than building URLs yourself.
{
"appointments": [
...
],
"total_entries": 1000,
"links": {
"next": "https://api.pracsuite.com/v1/appointment?page=3&page_size=100",
"self": "https://api.pracsuite.com/v1/appointments?page=2&page_size=100",
"previous": "https://api.pracsuite.com/v1/appointments?page=1&page_size=100"
}
}The API uses standard HTTP status codes. When something goes wrong, the response body includes a structured error object so your application can handle failures consistently.
{
"error": {
"status": 404,
"code": "NOT_FOUND",
"title": "Not Found",
"detail": "Could not find Patient with ID 12345"
},
"request_id": "..."
}The request_id helps Smartsoft identify the exact backend invocation if you need assistance.
You’ll typically see errors in these categories:
4xx series: client-side issues such as validation failures, missing parameters, or permissions.
5xx series: unexpected server errors. These are rare, and you can retry the request.
All requests are subject to rate limits and daily quotas. These limits apply per vendor key to ensure fair and consistent access across integration partners.
If you exceed the permitted request rate, you'll receive a 429 Too Many Requests response. If you reach your vendor usage quota, further requests will be blocked until the quota resets.
All timestamps returned by the API are in UTC, except for app_time. Appointment times are returned in the clinic’s tenant-level timezone so they reflect the local time the clinic operates in.
All date values follow this format: yyyy-MM-dd
All datetime values follow this format: yyyy-MM-dd'T'HH:mm:ss
All timestamp values follow this format: yyyy-MM-dd'T'HH:mm:ssz
The PracSuite API supports flexible server-side filtering through repeatable q[] query parameters. Each filter expression follows this pattern:
q[]=[FIELD]:[OPERATOR][VALUE]
You can include multiple q[] parameters in a single request. Each resource that supports filtering will list the available fields and the operators that apply to them.
| Operator | Description |
|---|---|
= | Equals |
!= | Doesn't equal |
< | Less than |
<= | Less than or equal to |
> | Greater than |
>= | Greater than or equal to |
Example:
q[]=date_of_birth:>=2000-01-01
| Operator | Description |
|---|---|
< | Less than |
<= | Less than or equal to |
> | Greater than |
>= | Greater than or equal to |
Equality is not supported due to millisecond precision.
Example:
q[]=created:<2024-06-01T00:00:00Z
| Operator | Description |
|---|---|
= | Equals |
!= | Doesn't Equal |
< | Less than |
<= | Less than or equal to |
> | Greater than |
>= | Greater than or equal to |
Example:
q[]=app_time:=2025-01-03T10:15:00
| Operator | Description |
|---|---|
= | Equals |
!= | Doesn't equal |
< | Less than |
<= | Less than or equal to |
> | Greater than |
>= | Greater than or equal to |
Examples:
q[]=practitioner_id:=123
q[]=duration:>=30
| Operator | Description |
|---|---|
= | Equals |
!= | Doesn't equal |
~ | Substring match |
Examples:
q[]=first_name:=John
q[]=first_name:!=Mary
q[]=first_name:~jo
| Operator | Description |
|---|---|
= | Equals |
!= | Doesn't equal |
Values must be true or false.
Example:
q[]=archived:=false
You can include as many q[] filters as you need in a single request. Each filter is evaluated on the server, and all filters must be satisfied for a record to be returned. This effectively works as an AND combination across all supplied conditions.
/appointment
?q[]=business_id:=5
&q[]=appointment_type_id:!=10
&q[]=app_time:>=2025-01-01T09:00:00
&q[]=app_time:<=2025-01-01T18:00:00
In this example:
Only appointments for business_id 5 are included
Appointments with appointment_type_id 10 are excluded
The appointment time must fall within the specified date range
You can combine filters on different fields, or apply multiple conditions to the same field (such as a start and end time). This gives you fine-grained control over the data returned.