Developers

Get started · PatientNow Pro

PatientNow Pro quickstart

Make your first authenticated PatientNow Pro API call in under ten minutes — no SDK required.

ℹ️ What is the PatientNow Pro API?

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:

⚠️ Treat credentials as secrets

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.

⚠️ This API writes to live data

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())
📎 Practice-scoped paths

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())

What's next