API reference
Four endpoints, no SDK, no key for reads. Everything speaks JSON in and JSON out.
https://<project>.supabase.co/functions/v1/json/<id>. Every example below is relative to that /json path.Read
No headers. No key. The response body is exactly the document you stored — not wrapped, not enveloped.
curl -s https://<base>/json/k3f9zq2mrt
Responses carry Content-Type: application/json; charset=utf-8, an X-Expires-At header with the deletion deadline, a short Cache-Control max-age, and Access-Control-Allow-Origin: * so browsers can call it directly.
- 200 — the document.
- 404 — unknown or expired ID, with a JSON error body.
Create
POST a body containing data, and optionally ttlHours and name.
curl -s -X POST https://<base>/json \
-H "Content-Type: application/json" \
-d '{"data": {"hello": "world"}, "ttlHours": 24, "name": "demo"}'
{
"id": "k3f9zq2mrt",
"url": "https://<base>/json/k3f9zq2mrt",
"editToken": "9f2c…",
"expiresAt": "2026-09-03T10:22:41.000Z",
"ttlHours": 24,
"owned": false
}
ttlHours is clamped to the ceiling that applies to you — 72 anonymous, 144 with a valid access token — by a database trigger, not just by the API. Ask for 999 and you get the ceiling, not an error.
The editToken is returned once and only its SHA-256 hash is stored. Lose it and an anonymous endpoint can no longer be changed; it will still expire on schedule.
Update
PUT replaces the whole document. Authorise with the edit token, or with a Supabase access token if you own the endpoint.
curl -s -X PUT https://<base>/json/k3f9zq2mrt \
-H "Content-Type: application/json" \
-H "X-Edit-Token: 9f2c…" \
-d '{"data": {"hello": "again"}}'
Include ttlHours to push the expiry out — still subject to the same ceiling, measured from now.
Delete
curl -s -X DELETE https://<base>/json/k3f9zq2mrt \
-H "X-Edit-Token: 9f2c…"
Errors
Every failure returns a JSON body of the shape { "error": "…", "code": "…" } with a matching HTTP status.
bad_request— 400, the body was not valid JSON.missing_data— 400, nodatafield.forbidden— 403, wrong or missing edit token and not the owner.not_found— 404, unknown or expired ID.too_large— 413, over 256 KB.method_not_allowed— 405.
Limits, stated plainly
- 256 KB per document, enforced both in the function and by a database constraint.
- 3 days maximum lifetime anonymously, 6 days signed in.
- Everything is public. There is no private mode. Anyone with the URL reads the document.
- Not for production. No uptime guarantee, no backups, no support contract. Use it to build, then move on.
API questions
It is the Supabase edge function for this deployment, shown in the endpoint URL you get after publishing. It is configured in one place — assets/js/config.js — so if the API later moves behind a custom domain, existing snippets are the only thing that need updating.
None. A GET needs no key, no token and no apikey header. That is the whole point — a plain fetch or curl works, including from a browser, because CORS is wide open on reads.
404 with a JSON error body explaining that it may have expired. Expired rows are filtered on read and physically purged on a schedule, so an expired ID never returns stale data.
No. GetJSON stores documents you publish; it does not capture arbitrary inbound POSTs into a log. A POST creates a new endpoint, it does not append to one.