Get started · PNE
PatientNow Essentials quickstart
Make your first authenticated PatientNow Essentials (PNE) API call in under ten minutes — no SDK required.
VISH customers use a slimmed-down API (a focused subset of resources). Follow the VISH quickstart → for that track. The base URL, authentication, and conventions are identical across both APIs.
Before you start
You need three things:
- A PatientNow Essentials account with API access enabled.
- Your gateway
apikeyand a username and password authorized to call the API — both are sent on every request (see Authentication). - The API base URL:
https://api.envisiongo.com/api/v1(shared by both APIs).
Anyone with your username and password has the same access your client does. Keep them out of source control, browser code shipped to end users, and logs. Prefer a dedicated API user over a person's login.
1 · Build your auth token
Every request needs two things: your gateway apikey
(on the query string) and an Authorization header containing the Base64
encoding of username:password. Build the token once:
# cURL builds and sends the Basic header for you with -u:
# -u "USERNAME:PASSWORD"
# ...or build it explicitly:
TOKEN=$(printf 'USERNAME:PASSWORD' | base64)
echo "Authorization: Basic $TOKEN"// Browser: btoa(); Node 16+: Buffer
const token = typeof btoa === "function"
? btoa("USERNAME:PASSWORD")
: Buffer.from("USERNAME:PASSWORD").toString("base64");
const authHeader = { Authorization: `Basic ${token}` };import base64
token = base64.b64encode(b"USERNAME:PASSWORD").decode()
headers = {"Authorization": f"Basic {token}"}
# Or let requests build it for you:
# from requests.auth import HTTPBasicAuth
# auth = HTTPBasicAuth("USERNAME", "PASSWORD")using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
var http = new HttpClient { BaseAddress = new Uri("https://api.envisiongo.com/api/v1/") };
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes("USERNAME:PASSWORD"));
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", token);2 · Confirm connectivity
Call GET /api/v1/status with your apikey and Basic
credentials. It needs no other input, so it's the cleanest way to prove your key,
token and base URL are correct.
curl "https://api.envisiongo.com/api/v1/status?apikey=YOUR_API_KEY" \
-u "USERNAME:PASSWORD"// Bake the apikey into the base URL so every call carries it:
const base = "https://api.envisiongo.com/api/v1";
const key = "YOUR_API_KEY";
const res = await fetch(`${base}/status?apikey=${key}`, { headers: authHeader });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
console.log(await res.json());import requests
base = "https://api.envisiongo.com/api/v1"
# A session with the apikey as a default param keeps every call clean:
s = requests.Session()
s.params = {"apikey": "YOUR_API_KEY"}
s.headers.update(headers)
res = s.get(f"{base}/status")
res.raise_for_status()
print(res.json())var res = await http.GetAsync("status?apikey=YOUR_API_KEY");
res.EnsureSuccessStatusCode();
Console.WriteLine(await res.Content.ReadAsStringAsync());A 200 OK with a JSON body means you're in. A 401
Unauthorized means the apikey, token or base URL is wrong — see
401 pitfalls. The python
session above sends the apikey on every call automatically; the
curl and js samples below add it to each request's query
string.
3 · Read real data
List customers. Results are paginated with Page and
Rows, and most list endpoints accept filters. Here we ask for the
first 5 customers with the last name "Smith":
curl "https://api.envisiongo.com/api/v1/customers?apikey=YOUR_API_KEY&LastName=Smith&Page=1&Rows=5" \
-u "USERNAME:PASSWORD"const params = new URLSearchParams({ apikey: key, LastName: "Smith", Page: "1", Rows: "5" });
const res = await fetch(`${base}/customers?${params}`, { headers: authHeader });
const customers = await res.json();
console.log(customers);# s (from step 2) already sends apikey on every call:
res = s.get(
f"{base}/customers",
params={"LastName": "Smith", "Page": 1, "Rows": 5},
)
print(res.json())Record IDs returned by the API are encrypted, URL-safe strings — not raw database integers. Pass them back exactly as received; don't try to parse or increment them. More in Guides → Resource IDs.
4 · Create a record
Write operations POST a JSON body. This creates a customer; the
response returns the new record's ID — e.g.
{"id": "QXVrT3RT…"} — which you then use to read or update it. (By
default the body is a JSON-encoded string; append
?responsetype=json to get a real JSON object instead.)
curl -X POST "https://api.envisiongo.com/api/v1/customers?apikey=YOUR_API_KEY" \
-u "USERNAME:PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"FirstName": "Ada",
"LastName": "Lovelace",
"Email": "ada@example.com",
"MobilePhone": "555-0100",
"IsActive": true
}'const res = await fetch(`${base}/customers?apikey=${key}`, {
method: "POST",
headers: { ...authHeader, "Content-Type": "application/json" },
body: JSON.stringify({
FirstName: "Ada",
LastName: "Lovelace",
Email: "ada@example.com",
MobilePhone: "555-0100",
IsActive: true,
}),
});
console.log(res.status, await res.json());res = s.post( # s carries apikey + auth headers from step 2
f"{base}/customers",
json={
"FirstName": "Ada",
"LastName": "Lovelace",
"Email": "ada@example.com",
"MobilePhone": "555-0100",
"IsActive": True,
},
)
print(res.status_code, res.json())Creating and updating records changes real data immediately — there is no separate sandbox environment. Test with disposable records you can clean up, and double-check the account behind your credentials before running writes.