Developers

Get started · PNE

PatientNow Essentials quickstart

Make your first authenticated PatientNow Essentials (PNE) API call in under ten minutes — no SDK required.

ℹ️ Building on VISH instead?

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:

⚠️ Treat credentials as secrets

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())
📎 IDs are opaque

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())
⚠️ This writes to live data

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.

What's next