Interchange technology stack · open to inspection

API status: which endpoint answers, which does not, and when we measured

This page says one thing only: on 2026-11-01, calling from the public internet, what each endpoint answered. It does not write "planned" or "coming soon", and it does not describe anything unimplemented as implemented.

★ Everything below is a measured reading from 2026-11-01. API status changes; the date on this page is what the reading is worth.
This is not a live status panel — it is a dated snapshot of readings. To judge whether an endpoint answers today, run the four steps in "how to check it yourself" below; that is more reliable than trusting this page.

1. Reading by reading

MethodPathMeasured answerWhat this one does / why this code
GET/healthz200 Public probe: answers only "is the service alive". No credential, no business data, no child process.
GET/readyz200 Public probe: readiness. When it answers something other than 200 (503, for example) it means "do not call in right now" — that is the job, not a fault.
GET/meta200 Public probe: the platform's identity (Interchange, ASTRALINK Holdings, standard_body:false). It is meant to be public.
POST/v1/devices401 Device registration. Stopped without a credential: a Bearer credential is required. 401 means "you did not identify yourself", not "broken".
POST/v1/devices/{id}/heartbeat401 Device heartbeat. As above: 401 without a credential; a Bearer credential is required.
POST/v1/billing/events401 Usage reporting. As above: 401 without a credential; a Bearer credential is required.
GET/proof/verify404 Proof-package verification, deliberately not open to the public internet. The reasons are in section 2; all three are hard reasons.
any/nope (any path that does not exist)404 The fallback: any route not on the register answers 404. This one is being measured too — it shows that "not registered means not automatically public".
GET/ (root of the API host)404 The API host serves no home page. Read the explanation on this site (neutralorbit.org); to call the API use the paths in the table above.

Note: the pages on this site (neutralorbit.org) and the API (api.neutralorbit.com) are two different things — the site is static pages, the API sits behind it. A page opening does not mean the API answers; whether an API answers is what the table above records.

2. Why /proof/verify is 404 on the public internet

This is not "not finished yet"; it is "finished but not exposed". Three reasons, any one of which would be enough on its own; together they would be a hole opened into the public internet:

  1. It has no authentication: anyone can call it, with no credential.
  2. It starts a child process to run the verifier, and a single request can run for up to 120 seconds: one public address would be enough to occupy the machine's processor.
  3. It is outside the rate limit: the rate limit applies only to the three write endpoints above, so calling it does not trigger "too many requests".

All three together = no authentication + no rate ceiling + a process per request. To let partners use it, it first has to become "credential required + its own rate limit", and then be allowed through on its own; until then, the public internet gets 404.

3. Only four routes are exposed publicly (hard-coded, listed one by one)

Exposure is not "open a prefix"; it is written out one route at a time:

  • POST /v1/devices — device registration
  • POST /v1/devices/{id}/heartbeat — heartbeat ({id} is exactly one segment, no slash)
  • POST /v1/billing/events — usage reporting
  • GET /healthz, /readyz, /meta — the three public probes

Everything else (including /proof/verify, and any path "newly added to the service but not entered on the exposure list") falls to the last rule: 404. The cost of this arrangement is that "adding an endpoint means changing two places"; the benefit is that a new endpoint does not become public just because someone wrote a prefix. The 404s for /nope and / above are the measured evidence for that rule.

4. How to check it yourself (four steps, no login)

  1. Take any tool that can send a request (a command line, a browser address bar, a short script of your own).
  2. Call GET /healthz: it returns 200 and the body's status is ok ⇒ the service is alive.
  3. Call GET /readyz and GET /meta: both should also be 200. /meta should show Interchange and ASTRALINK Holdings.
  4. Call the three write endpoints (POST /v1/devices and the others) without a credential: the answer should be 401.

Step 4 is the key reverse test: if you get 200 without a credential, our door is broken — please write and tell us (the address is on the Connect page). That matters more than using the API yourself.

5. Credentials, rate limits and lockout (the rules behind the readings)

ItemHow it works todayWhere the reading comes from
How to present a credentialHeader Authorization: Bearer <credential>; a single X-Api-Key header is also acceptedMeasured: none supplied → 401
What a credential looks likeMANUAL-KEY: plus 32 random lowercase hexadecimal characters. Old sequential forms (like KEY-2026-0001) are rejected outright — something you can guess in three tries is not a keyMeasured: with a real credential as a base, 100 guessed strings, all 100 answered 401
How it is issuedA manual ledger: one line per credential, issued through no self-service entry pointHence there is no "register and get a credential" today
Consecutive rejectionsThe same credential rejected 5 times in a row ⇒ locked for 15 minutes; during the lock even the correct credential is refusedMeasured: 5 rejections → the 6th call (credential now correct) still refused
Too many requestsThe same credential is allowed at most 60 requests in 60 seconds; beyond that it is refused and told how many seconds remainMeasured: 60 passed and the 61st refused
RevocationMark the line as revoked and re-sign ⇒ the next request cannot get in, with no restartMeasured: change one line, the same request goes from passing to 401
Insufficient permissionThe credential is valid but lacks this permission ⇒ 403 (not 401: the identity is fine, and retrying will not help)Measured: a credential with only usage-reporting permission gets 403 on device registration
Ledger alteredEvery line carries a signature; change one character and that line is void on the spot (only that line, not the whole book)Measured: change one character ⇒ the request for that line answers 401

The last four rows are "verification on the API side": 401 with no credential, 403 beyond permission, revocation effective immediately, and rejection once the ledger is altered. The test records for these four can be supplied on request — write and ask, see Connect.
The three thresholds (5 times / 15 minutes / 60 requests / 60 seconds) are proposed values, awaiting joint confirmation by the security side and the commercial side; this page only shows that the gate works at these values.

6. What this page does not say (so that it is not read as more than it is)

  • No live panel: there is no "currently online count" or "success rate over the last hour". For those, measurement collection has to exist first, and that step is not done.
  • No service-level commitment: this page does not promise availability. A commitment belongs in a contract; this page gives readings only.
  • No "test environment entry": the test environment does not exist yet, so this page does not write a made-up address. See Connect.
  • No guarantee beyond TLS: the public-internet leg is encrypted; but authentication on the API side still puts the credential in clear text in a header. That is written here, not hidden.

Next step

Readings read; the next step is connecting those three write endpoints.

Go to Connect →