Get started · PatientNow Pro
PatientNow Pro quickstart
Make your first authenticated PatientNow Pro API call in under ten minutes — no SDK required.
PatientNow Pro (PNP) is a REST API for the PatientNow Pro product. It covers
patients, appointments, scheduling availability, waitlists, billing, and reference
data — all scoped under a practice ID path prefix. Unlike PNE and
VISH, PNP uses a single token-based auth scheme (no gateway
apikey parameter). If you're integrating with PatientNow Essentials,
see the PNE quickstart → instead.
Before you start
You need two things:
- A PatientNow Pro practice ID — the identifier that scopes
every request to your practice (appears in the path as
{practiceId}). - An authorization token — sent as an
Authorizationheader on every request.
Anyone with your token has the same API access you do. Keep it out of source control, browser code shipped to end users, and logs. Use a dedicated service token rather than a person's credentials where possible.
There is no sandbox environment. Write operations (POST/PUT) affect real practice data immediately. Test with records you can clean up, and confirm the practice ID you're using before running writes.
1 · Add your token to requests
Every PNP request needs an Authorization header containing your
token. Set it once and reuse it:
# Pass your token in the Authorization header on every request:
curl "https://backend-production.patientnow.net/backend/patientnowpro/..." \
-H "Authorization: YOUR_TOKEN"const base = "https://backend-production.patientnow.net/backend/patientnowpro";
const authHeader = { Authorization: "YOUR_TOKEN" };import requests
base = "https://backend-production.patientnow.net/backend/patientnowpro"
# A session with the token as a default header keeps every call clean:
s = requests.Session()
s.headers.update({"Authorization": "YOUR_TOKEN"})using System;
using System.Net.Http;
using System.Net.Http.Headers;
var http = new HttpClient {
BaseAddress = new Uri("https://backend-production.patientnow.net/backend/patientnowpro/")
};
http.DefaultRequestHeaders.Add("Authorization", "YOUR_TOKEN");2 · Confirm connectivity
The cleanest first call is GET /practices/{practiceId}/patients —
it lists patients in your practice, requires valid auth, and confirms that your
token and practice ID are correct. A 200 OK means you're in.
curl "https://backend-production.patientnow.net/backend/patientnowpro/practices/YOUR_PRACTICE_ID/patients?Limit=1" \
-H "Authorization: YOUR_TOKEN"const practiceId = "YOUR_PRACTICE_ID";
const res = await fetch(
`${base}/practices/${practiceId}/patients?Limit=1`,
{ headers: authHeader }
);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
console.log(await res.json());practice_id = "YOUR_PRACTICE_ID"
res = s.get(
f"{base}/practices/{practice_id}/patients",
params={"Limit": 1},
)
res.raise_for_status()
print(res.json())var practiceId = "YOUR_PRACTICE_ID";
var res = await http.GetAsync($"practices/{practiceId}/patients?Limit=1");
res.EnsureSuccessStatusCode();
Console.WriteLine(await res.Content.ReadAsStringAsync());A 401 Unauthorized means your token is missing or invalid. A
403 Forbidden means your token doesn't have access to that practice
ID.
3 · Read real data
List today's appointments for your practice. Results are paginated
with Page and Limit parameters. You can filter by date
with ApptDate:
curl "https://backend-production.patientnow.net/backend/patientnowpro/practices/YOUR_PRACTICE_ID/appointments?Page=1&Limit=5" \
-H "Authorization: YOUR_TOKEN"const params = new URLSearchParams({ Page: "1", Limit: "5" });
const res = await fetch(
`${base}/practices/${practiceId}/appointments?${params}`,
{ headers: authHeader }
);
console.log(await res.json());# s (from step 1) already sends the Authorization header on every call:
res = s.get(
f"{base}/practices/{practice_id}/appointments",
params={"Page": 1, "Limit": 5},
)
print(res.json())Every PNP endpoint is prefixed with
/practices/{practiceId}/. Keep your practice ID handy — you'll
pass it on every call. IDs returned by the API for records (patients,
appointments, etc.) are integers, not opaque strings as in PNE/VISH.
4 · Create a record
Write operations POST a JSON body. This creates a new patient record.
On success the API returns 201 Created with the new patient object,
including the assigned patient ID you use for subsequent reads and updates.
curl -X POST \
"https://backend-production.patientnow.net/backend/patientnowpro/practices/YOUR_PRACTICE_ID/patients" \
-H "Authorization: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Jane",
"lastName": "Smith",
"dob": "1985-03-15T00:00:00",
"personalInfo": { "email": "jane.smith@example.com" },
"presentAddress": { "cell": "555-000-1234" }
}'const res = await fetch(`${base}/practices/${practiceId}/patients`, {
method: "POST",
headers: { ...authHeader, "Content-Type": "application/json" },
body: JSON.stringify({
firstName: "Jane",
lastName: "Smith",
dob: "1985-03-15T00:00:00",
personalInfo: { email: "jane.smith@example.com" },
presentAddress: { cell: "555-000-1234" },
}),
});
console.log(res.status, await res.json());res = s.post( # s carries Authorization header from step 1
f"{base}/practices/{practice_id}/patients",
json={
"firstName": "Jane",
"lastName": "Smith",
"dob": "1985-03-15T00:00:00",
"personalInfo": {"email": "jane.smith@example.com"},
"presentAddress": {"cell": "555-000-1234"},
},
)
print(res.status_code, res.json())