Developers

Get started

Authentication

Both the PatientNow Essentials (PNE) and VISH APIs require two things on every request: your gateway API key (an apikey parameter) and HTTP Basic user credentials. There are no anonymous endpoints.

ℹ️ Same scheme, both APIs

Authentication is identical for PNE and VISH, and both share the same host (api.envisiongo.com) — your gateway key determines which API your account can reach. Send the apikey on every call, and identify the user with Basic auth (header).

The auth scheme

Every request carries two credentials:

  1. An apikey — your gateway key, identifying your integration to the API gateway. Send it on every call.
  2. HTTP Basic user credentials — a username and password, Base64-encoded, identifying the acting user. The API validates them against an active user on each call; there is no login step or bearer token to exchange.
⚠️ Always use HTTPS

Auth puts your key and credentials on every request. Only call the API over https:// so they are never sent in clear text. Use a dedicated API user, not a real person's login, and rotate credentials if they are ever exposed.

Your gateway key (apikey)

The apikey is issued to your integration and is required on every request, in addition to the Basic user credentials below. Pass it as an apikey query-string parameter:

# apikey on the query string + Basic user credentials in the header:
curl "https://api.envisiongo.com/api/v1/status?apikey=YOUR_API_KEY" \
  -u "USERNAME:PASSWORD"
const token = btoa("USERNAME:PASSWORD"); // Node: Buffer.from(...).toString("base64")
const res = await fetch(`${base}/status?apikey=YOUR_API_KEY`, {
  headers: { Authorization: `Basic ${token}` },
});
from requests.auth import HTTPBasicAuth
res = requests.get(
    f"{base}/status",
    params={"apikey": "YOUR_API_KEY"},
    auth=HTTPBasicAuth("USERNAME", "PASSWORD"),
)
// Append apikey to the query string; Basic header set on the client (below).
var res = await http.GetAsync("status?apikey=YOUR_API_KEY");
📎 apikey vs. user credentials

They are different things. The apikey identifies your integration to the gateway; the Basic username/password identify the user whose permissions the call runs under. You need both — the apikey alone won't authenticate a user, and Basic auth alone won't pass the gateway.

Send the Base64 of username:password in the standard Basic Authorization header. Most HTTP clients build this for you when you supply a username and password.

# Let cURL build the header (apikey still required on the query string):
curl "https://api.envisiongo.com/api/v1/status?apikey=YOUR_API_KEY" \
  -u "USERNAME:PASSWORD"

# Equivalent explicit header:
curl "https://api.envisiongo.com/api/v1/status?apikey=YOUR_API_KEY" \
  -H "Authorization: Basic $(printf 'USERNAME:PASSWORD' | base64)"
const token = btoa("USERNAME:PASSWORD"); // Node: Buffer.from(...).toString("base64")
const res = await fetch(`${base}/status?apikey=YOUR_API_KEY`, {
  headers: { Authorization: `Basic ${token}` },
});
from requests.auth import HTTPBasicAuth
res = requests.get(
    f"{base}/status",
    params={"apikey": "YOUR_API_KEY"},
    auth=HTTPBasicAuth("USERNAME", "PASSWORD"),
)
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes("USERNAME:PASSWORD"));
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", token);
var res = await http.GetAsync("status?apikey=YOUR_API_KEY");
📎 What gets encoded

The Base64 value is the literal string username:password joined by a single colon. The username itself must not contain a colon. Base64 is encoding, not encryption — it is trivially reversible, which is exactly why HTTPS is mandatory.

Header-less user token (api_key)

Where you genuinely can't set an Authorization header, the Base64 username:password token may instead be passed as an api_key query parameter (note the underscore — this is distinct from the gateway apikey above). Its value is identical to what you'd put after Basic in the header. The gateway apikey is still required alongside it.

curl "https://api.envisiongo.com/api/v1/status?apikey=YOUR_API_KEY&api_key=BASE64_OF_USER_COLON_PASS"
⚠️ Prefer the header

Query strings are routinely written to server logs, proxy logs, and browser history. Putting the user token there widens its exposure. Use api_key only when headers are genuinely unavailable, and never in URLs that end users can see.

Base URL

Both APIs share a single base URL — the host plus the versioned api/v1 path:

https://api.envisiongo.com/api/v1

So a typical full URL is https://api.envisiongo.com/api/v1/customers. There is no per-customer path prefix — your gateway apikey (not the URL) determines which API and account a request resolves to.

APIBase URLFirst call to try
PatientNow Essentials (PNE)https://api.envisiongo.com/api/v1GET /api/v1/status
VISHhttps://api.envisiongo.com/api/v1GET /api/v1/companies

Both APIs share the host api.envisiongo.com; your gateway apikey determines which one your account reaches. VISH has no status endpoint, so its cleanest connectivity check is GET /api/v1/companies — see the VISH quickstart.

Common 401 causes

A 401 Unauthorized means the request was rejected before your data was touched. Work through these in order:

SymptomLikely causeFix
401 on every callMissing the gateway apikey, or missing the Authorization headerSend both?apikey=… on the URL and Basic credentials. Confirm the header isn't dropped on redirects.
401 with a valid user, on every callWrong or unprovisioned apikey (e.g. used the underscore api_key token in place of the gateway key)Use your gateway apikey (no underscore); confirm it's provisioned for the API you're calling.
401 with a token you "know" is rightEncoded username : password with spaces, or wrong separatorEncode exactly username:password — one colon, no spaces.
401 after it worked beforePassword changed, or user deactivatedRe-issue credentials; the user must be active.
401 only in the browserCredentials not reaching the API across a redirect or CORS preflightCall the canonical https URL directly; avoid http→https redirects.
Works in cURL, fails in codeDouble-encoding (encoding an already-encoded token)Base64 the raw user:pass once, not the header value.
📎 401 vs 403 vs 404

401 = not authenticated (bad/missing credentials). A request that authenticates but lacks permission, or asks for a record that isn't visible, may instead come back as 404 Not Found. If you get a 404 on a record you expect to exist, re-check the ID and that the authenticated user can see it.

Pre-flight checklist