Record API
Read the GhostPost.us record from inside your own product
GhostPost.us is an outside-in evidence and observation layer — read-only middleware between configured public job sources and downstream compliance, HR, and legal systems. It delivers the record; it does not execute remediation. Your product owns the interface, the workflow, and the decision. GhostPost.us supplies the dated, sourced record underneath it.
What GhostPost.us provides and the boundaries of the Record API
Coverage is limited to the sources configured and available for observation.
What the API provides
- Observe the public sources it is configured and able to reach
- Record what each of those sources displayed
- Timestamp every observation
- Preserve observation history
- Show changes between successful observations
- Surface requirement records with their sources, where available
- Provide read-only access to the recorded observations
Where the boundary sits
The API returns observations. It carries no review status, no assignment, no resolution state, no severity, no score, and no verdict about an employer. Those are your product's to define — which is exactly why the record stays neutral enough for two systems that disagree to cite the same evidence.
Every endpoint is a read. Nothing in v1 writes, charges, or mutates the record.
Authentication
Server-to-server only. There is no browser API and no CORS surface — a key in client code is a key anyone can read.
Header
Authorization: Bearer gp_live_...
Keys are issued per workspace, from the Workspace tab, and scoped to that workspace's own record. GhostPost.us stores only a fingerprint, so a key is shown exactly once. A revoked key stops reading immediately; the record itself is untouched.
Test mode
Build the integration before your workspace holds a single observation.
A gp_test_ key calls the same endpoints and returns the same shape, backed by a fixed sample employer: greenhouse/sample-employer. The values never change between calls, so your integration tests stay stable.
The rule that matters
Test data is visually and programmatically distinguishable from live data: every sandbox payload carries mode: "test", sample: true, an X-GhostPost.us-Mode: test header, and an employer named "Sample Employer (GhostPost.us test data)".
No test response may be represented as a real GhostPost.us observation, a customer record, or a Field Test result. Test and sample records must never be mixed with live workspace observations — including in exports, histories, analytics, or anything your product displays downstream.
Sandbox call
curl -s https://ghostpost.us/api/public/v1/companies \ -H "Authorization: Bearer gp_test_..."
Endpoints
Seven reads. That is the whole surface.
GET /api/public/v1
Discovery — the contract and the endpoint index.
GET /api/public/v1/companies
Every company this workspace holds a record for.
GET /api/public/v1/companies/{provider}/{account}
One employer source: evidence plus source coverage.
GET /api/public/v1/companies/{provider}/{account}/observations
Evidence — the observation history, timestamped and sourced.
GET /api/public/v1/companies/{provider}/{account}/coverage
Monitor — each recorded read attempt and how it went.
GET /api/public/v1/companies/{provider}/{account}/changes?since=ISO8601
Watch — what changed between observations.
GET /api/public/v1/requirements?jurisdiction=California
Requirements — the records held for named jurisdictions.
The machine-readable contract is OpenAPI 3.1, served without a key at /api/public/v1/openapi.json. Generate a client from it.
Quickstart
Same read, three languages.
cURL
curl -s https://ghostpost.us/api/public/v1/companies \ -H "Authorization: Bearer gp_live_..."
TypeScript
const res = await fetch(
"https://ghostpost.us/api/public/v1/companies/greenhouse/sample-employer/changes?since=2026-07-01T00:00:00Z",
{ headers: { Authorization: `Bearer ${process.env.GHOSTPOST_API_KEY}` } },
);
if (res.status === 429) {
// Operating limit. Retry-After is in seconds.
const wait = Number(res.headers.get("retry-after") ?? 60);
}
const body = await res.json();
if (body.mode === "test") {
// Sample data. Never store or display it as a real observation.
}Python
import os, requests
r = requests.get(
"https://ghostpost.us/api/public/v1/companies/greenhouse/sample-employer/observations",
headers={"Authorization": f"Bearer {os.environ['GHOSTPOST_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
data = r.json()
assert data["mode"] == "live", "test payloads must never enter the live store"
for line in data["observations"]:
print(line["observedAt"], line["kind"], line["summary"])Evidence semantics your system must honor
These are the rules that make the record worth citing. A consuming product that breaks them turns evidence back into assumption.
Observed
Stated absent
Can't determine
Source unavailable
No requirement record identified
Unverified
- An unread source is unread. Never display it as “no postings”, “clean”, or “nothing found”.
- Every line carries an observation time and the source it came from. Keep both when you store or display it.
- GhostPost.us states what was observed. Do not present a GhostPost.us line as a determination, a violation, a score, or a risk rating.
- Test and sample records must never be mixed with live workspace observations — not in exports, histories, analytics, or downstream displays.
- Coverage is limited to the sources configured and available for observation.
Operating limits, request IDs, and errors
Rate limit
120 requests per minute per key to start. Over the limit returns 429 with a Retry-After header in seconds. Higher limits are a configuration change, not an integration change — ask if you need one.
Request IDs
Every response carries X-GhostPost.us-Request-Id and the same value in the body as requestId. Log it; quote it in a support thread and we can find the exact read.
Errors
401 missing or invalid key · 404 this workspace holds no record for that source · 429 over the operating limit. Every error body has error.code and error.message.
Versioning
The path is versioned (/v1) and every payload carries apiVersion. Fields are added, not removed or repurposed, within a version.
Get access
Workspace owners and admins issue live and test keys from the Workspace tab. For partner integrations, request access and tell us what you are building.