API and MCP reference

The same screening engine this website calls, reached by your own software. 11 HTTP endpoints and one MCP endpoint, over one set of actions — there is no second implementation behind either, so an answer here and an answer in the interface cannot disagree.

What this page is notNot on sale

It is a reference, not a way in. Programmatic access comes with the API & Automation plan, and that plan is not on sale — there is no checkout for it and nothing on this site will issue you a credential. The accounts that hold keys today were provisioned by us directly, under terms agreed with them; there is no self-serve route onto this plan. This page is written for them, and for anyone judging whether the surface is worth building against. No date is promised here; the pricing page is where the plan’s status is stated, and where the plans that are arranged rather than bought are listed.

Authenticating

One header, and nothing else. A key is not accepted in a query string or in a second header: a query string is written to access logs by default, and a credential that can arrive two ways is one a future reader has to check twice before believing it cannot arrive a third.

curl https://gridcite.com/api/agent/projects \
  -H "Authorization: Bearer YOUR_GRIDCITE_API_KEY"

Keys are created and revoked in the account panel, which is cookie-authenticated in a browser. A key cannot mint another key — that is deliberate, because a credential that renews itself makes revocation mean nothing. The full secret is shown once, at the moment it is created, and only a hash is stored afterwards; “show it to me again” is a request nothing can satisfy, so capture it then.

Arguments to a GET travel in the query string, where every value is text — ?decision=advance, ?includeArchived=true. Arguments to a POST or PATCH travel in a JSON body. A value named in the path is read from the path and cannot be overridden by either.

Endpoints

Every description below is the tool’s own, imported rather than rewritten, so what you read here is exactly what a model reading tools/list is told. Each one states the boundary as plainly as the capability, because a description that oversells is not a marketing problem — it is a wrong answer delivered at speed.

Every response has the same shape

Success, refusal and outage all return the same fully populated envelope, so one parser handles every reply and a caller that renders it blindly gets an honest empty result rather than a crash — which matters most in exactly the situation that produces one.

An unknown is a value, never a blank and never a zero

Every measurement arrives as a reading. When nobody has established it, the reading is still there and its value is the literal string unknown or not_published. Never an omitted key, never null in a numeric field, and above all never 0 — a 0 acre figure or a 0 mile distance reads as “we measured it and there is none”, which is the false negative that ends a real site.

The two literals are different facts and a developer acts on them differently. unknown means nobody established it and an import or a survey might; not_published means the authority that would know does not publish it, so no amount of our work produces it and the next step is a phone call. Each unknown carries what would resolve it.

The same rule governs change: changes distinguishes “two assessments were compared and agreed” from “the sweep has not reached this site twice”. Collapsing those would let “we have never checked” render as calm.

How well established a value is

Every finding carries a tier and every reading carries a confidence, and both are the same six-value scale, strongest first. This is the vocabulary that decides what a caller is entitled to do with a number — a provisional figure ranks a shortlist and does not support a commitment, and conflicting is weaker than knowing nothing.

These are hyphenated. The tier is “not-published”; a reading’s value for the same fact is “not_published”. They are the same fact in two places, and a switch written against one spelling matches half the payload.

evidence.confidence is a different field on a different scale — high, medium, low — and it is a verdict over the whole result rather than over one value. Two fields named confidence with different value sets is a trap nobody avoids by accident, so it is named here.

A reading, wherever a measurement appears

Measurements inside data are never bare values. Branch on known.

A finding, under risks

A step, under nextActions

Two axes, and they are separate: priority says how urgent, establishment says how well established the finding behind it is. A fatal step whose establishment is not established is an open question, not a rejection.

Statuses, and whether to retry

Branch on status in the body rather than on the HTTP code. When an action ran, the two correspond:

unavailable never collapses into a 404. A project that could not be read because the store is down has not been shown to be absent, and answering “no such project” during our outage would tell you your pipeline was deleted. An error nobody planned for answers 500 with unavailable in the body — both are 5xx, so retry either way.

Refusals, before any action runs

These are decided by the gate, so nothing was computed and nothing was metered. They still arrive as the same envelope.

No Retry-After header accompanies either 429. The limiter falls back to a per-instance rolling window when the shared counter is unreachable, so the remaining time is not a figure we always have — and a wrong Retry-After is worse than none, because a client trusts it and comes back to another refusal.

How calls are counted

One action call is one unit. Not rows, not tokens, not requests. One screening call is one unit whether it screened two sites or two hundred. It is the only unit you can predict before you call, and it does not move when our implementation gets faster or slower.

A call is counted once the action produced an answer, whatever that answer says — a not_found is real work and is counted. A refusal by the gate is never counted, and neither is a request whose arguments were rejected before anything ran. Every metered response carries a usage field with the reading after that call; null there means no reading was taken, not zero.

There is never an automatic charge. Not at the warning, not past the included amount, not at the pause. Going over is a conversation about the right allowance, never an invoice, and every usage notice says so in its own words.

A separate per-hour ceiling applies per key rather than per account, so a retry loop in one integration cannot take down the same account’s nightly job. It is a safety interlock and not a quota: its refusal names the rate and never speaks in the allowance’s words, because somebody with a retry bug must not be sent to buy a bigger plan.

MCP

The same tools, the same envelopes and the same meter, over JSON-RPC at a single endpoint:

POST /api/agent/mcp

The methods implemented are initialize, tools/list, tools/call, ping. tools/list is discovery — it returns the names, descriptions and JSON Schemas above — and it is not metered. Only tools/call is counted. Every method is still authenticated and still passes through the per-hour ceiling, because a loop calling tools/list is the same runaway as a loop calling anything else.

The server is stateless: no session id is issued and none is read. Every request carries its own key and is authenticated, limited and metered on its own. Batched arrays are refused — one HTTP request is one authentication and one limit decision, so a 500-item array would be 500 action calls behind a single check.

A protocol failure — bad JSON, an unknown method, a missing tool name — is a JSON-RPC error. A tool failure, where the action ran and answered not_found or invalid, is a result with isError set, carrying the whole envelope. That split is what lets a caller tell “I called this wrong” from “the answer is that there is no such project”.

The endpoint list on this page is checked against the route files themselves, and every description is imported from the tool definition both surfaces share, so this page cannot document an endpoint that does not exist or describe one differently from the schema your agent reads. GridCite is preliminary GIS screening: nothing returned by any endpoint here is a survey, a title review, an interconnection study or a permit decision — see the Site-Screening Disclaimer.