Data Integration Guide
v1.0
HealthCORE Tech — Neon Data API

Data Integration Guide

This guide provides the information needed to authenticate and query data from the HealthCORE Tech Neon database via our REST API. Each available table is documented below with its description, source name, and notes on terminated-record segmentation where applicable.


Authentication

All requests require a short-lived Bearer token. Tokens expire after 10 minutes (600 seconds) and must be refreshed before that window closes.

1
Request a token

POST your credentials to the token endpoint:

POST https://api.hctech.io/neonauth/token
Request body
{
  "username": "your_username",
  "password": "your_password"
}

On success the response contains:

{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "tokenType": "Bearer",
  "expiresInSeconds": 600,
  "scope": "neon.read"
}
Note

Tokens expire after 10 minutes. Refresh proactively — for example at 540 seconds — or handle 401 Unauthorized by re-authenticating immediately.

2
Include the token on every request

Pass the accessToken value as a Bearer token in the Authorization header:

Header
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
cURL — complete auth + query
# Step 1: obtain token
TOKEN=$(curl -s -X POST https://api.hctech.io/neonauth/token \
  -H "Content-Type: application/json" \
  -d '{"username":"your_user","password":"your_pass"}' \
  | jq -r '.accessToken')

# Step 2: query a table
curl -X GET \
  "https://ep-delicate-firefly-aahtome3.apirest.westus3.azure.neon.tech/neondb/rest/v1/colstat?limit=100" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json"

Making Requests

Data is accessed through the Neon Data API, a PostgREST-compatible REST interface. Filters, sorting, and pagination are expressed as URL query parameters. Every request must include your Bearer token.

Base URL

BASE https://ep-delicate-firefly-aahtome3.apirest.westus3.azure.neon.tech/neondb/rest/v1

Append the table name to query it:

GET …/rest/v1/{table_name}?{filters&options}

Required headers

Headers Required
Authorization string Bearer {accessToken} from the auth endpoint
Content-Type string application/json
Prefer string Optional. Send count=exact to receive a total row count in the Content-Range response header.
Tip

Neon provides an interactive SQL to REST Converter that translates SQL SELECT statements into equivalent URL parameters.


Data Tables

Each table includes its Neon table name, field structure, description, and terminated-record guidance where relevant.


Query Reference

All filtering, sorting, and pagination use PostgREST URL conventions.

Filter operators

OperatorMeaningExample
eqEquals?facilityid=eq.42
neqNot equals?charge=neq.true
gtGreater than?date=gt.2024-01-01
gteGreater than or equal?date=gte.2024-01-01
ltLess than?count=lt.100
lteLess than or equal?count=lte.100
likePattern match (case-sensitive)?cptcode=like.992*
ilikePattern match (case-insensitive)?name=ilike.*smith*
isIs null / not null?date=is.null
inValue in list?state=in.(CA,TX,NY)

Sorting, pagination & column selection

ParameterDescriptionExample
selectColumns to return (comma-separated)?select=facilityid,date,count
orderSort by column — append .asc or .desc?order=date.desc
limitMaximum rows to return?limit=500
offsetRows to skip, used with limit for paging?limit=500&offset=1000

Example — filtered, sorted, paginated

cURL
curl -X GET \
  "https://ep-delicate-firefly-aahtome3.apirest.westus3.azure.neon.tech/neondb/rest/v1/pvstat
    ?select=facilityid,date,excfromstats,charge,count
    &facilityid=eq.42
    &date=gte.2024-01-01
    &order=date.desc
    &limit=500
    &offset=0" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json"

Getting total row count

Add Prefer: count=exact to receive the total number of matching rows in the Content-Range response header.

cURL — with row count
curl -X GET \
  "https://ep-delicate-firefly-aahtome3.apirest.westus3.azure.neon.tech/neondb/rest/v1/pvstat?limit=500&offset=0" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Prefer: count=exact"

# Response header:
# Content-Range: 0-499/18342

Querying terminated records

Tables that include a _terminated variant must be queried separately. Terminated records are not present in the base table. The schema is identical between the two tables — all query parameters apply equally to both.

cURL — base vs. terminated
# Active records
curl "…/rest/v1/colstat?limit=500" -H "Authorization: Bearer $TOKEN"

# Terminated records
curl "…/rest/v1/colstat_terminated?limit=500" -H "Authorization: Bearer $TOKEN"
Important

The _terminated tables are updated on a separate, less frequent schedule and are not included in the nightly sync. If your integration requires a complete dataset, ingest both tables and union them in your system.


Rate Limits & Best Practices

600s
Token lifetime
Refresh before expiry to avoid 401 errors
1,000
Default row limit
Rows returned per request when no limit is specified
HTTPS
Transport only
All connections must use TLS — plain HTTP is rejected
READ
Credential scope
Issued credentials are read-only (neon.read)

Pagination

Always paginate using limit and offset rather than requesting a full table at once. A page size of 500–1,000 rows is generally optimal.

JavaScript — paginate through a full table
const BASE = "https://ep-delicate-firefly-aahtome3.apirest.westus3.azure.neon.tech/neondb/rest/v1";
const PAGE = 1000;

async function fetchAll(table, token) {
  const rows = [];
  let offset = 0;

  while (true) {
    const res = await fetch(`${BASE}/${table}?limit=${PAGE}&offset=${offset}`, {
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
        Prefer: "count=exact",
      },
    });

    if (!res.ok) throw new Error(`HTTP ${res.status}`);

    const page = await res.json();
    rows.push(...page);

    const total = parseInt(res.headers.get("Content-Range")?.split("/")[1] ?? "0");
    if (rows.length >= total || page.length === 0) break;
    offset += PAGE;
  }

  return rows;
}

Recommendations

  • Use select=col1,col2 to request only the columns your integration needs — reduces payload size on wide tables.
  • Refresh tokens proactively rather than waiting for a 401 response.
  • Use a date-based filter with gte. for incremental syncs rather than pulling full tables on every run.
  • If a complete dataset is required, ingest the base table and its _terminated variant separately, then union them in your system.
  • Implement exponential backoff if you receive 429 Too Many Requests.

Request Access

If you do not yet have credentials, or need to provision access for a new team member, contact the HealthCORE Tech support team.

Need API Credentials?

Send your name, organization, and a brief description of your use case.