castomAPI
Get your key

Written down, then measured

Security

No certificate is claimed on this page, because none has been issued yet. What is claimed is specific, and each claim is something you can test against the API.

Tenancy

Every key belongs to one account, and every stored thing — a platform connection, a custom endpoint, a document — is scoped to that account and, where the product declares one, to a project. A resource that exists but is not yours answers exactly as one that does not exist: a 404 with zero cost and an identical body. Enumeration by 403 is not possible here by design.

Custom code

A custom endpoint runs in its own V8 isolate per request, with two seconds of CPU and 128 MB of memory. It has no network. The one bridge it has, $safeFetch, executes on the host with the host's network position — so its policy is the part that matters: it resolves the hostname before connecting, refuses any address outside the public unicast range in v4, v6 or v4-mapped-v6 form, follows redirects manually and re-validates every hop. The policy lives in a module with no native dependency, so it is tested without a native build.

Server-side requests

The utility endpoints that fetch a URL — scrape, crawl, screenshot, proxy, safe-fetch — go through the same guard: hostname resolved first, every returned address checked, every redirect re-validated, response size capped. Where a browser is involved (screenshots, the UX audit) the residual DNS-rebinding window is documented rather than denied.

Platform connections

An integration connects the end user's own account. Tokens are stored encrypted (AES-256-GCM) and refreshed on demand; a family whose provider rotates the refresh token on every use is handled per grant, so sibling connections never end up holding an invalidated credential. The consent URL is minted only from a dashboard session, never from an API key — whoever holds the CSRF state decides which account gets connected, and that must be the person in the browser. The state nonce is consumed atomically.

Identifiers in paths

Every id spliced into an upstream path is checked against an anchored pattern before it is used, including ids that arrive from a provider's own response. encodeURIComponent does not close this class — dots survive it — so the check is a real assertion, on the schema and in the handler.

Billing correctness is a security property

A 200 that is not a success is money charged for work not done. Provider responses are classified where they are consumed, mechanically, so ok: false, userErrors, per-item batch statuses and their cousins turn into unbilled errors rather than paid successes. Partial success bills per successful item, never per call.

This website

castomapi.com loads scripts only from this website and from two services run by Castomo — our own Observer analytics, which stores nothing on your device, and the chat button — sets no cookie, calls no third-party analytics and serves its own fonts. A content security policy in the head of every page — default-src 'self', script-src limited to this site plus observer.castomo.com and chat.castomapi.com, object-src 'none' — is enforced by your browser, so a tracker added by mistake would fail loudly instead of quietly. The one inline script, the theme bootstrap, is allowed by hash.

Reporting

Found something? Write to api@castomo.com with "security" in the subject. security.txt says the same in the format researchers expect.