getting started
curl it and follow the links
getting started
gnu.foo is a hypermedia api — curl it and follow the links.
the root
curl gnu.foognu.foo proxies cli requests to api.gnu.foo — use either. browser requests serve the web ui, cli clients get plain text. all api urls below work with both domains.
every response includes _links with available actions — no docs needed to navigate. that's the point of hypermedia.
using tools
tools take positional args as path segments:
curl gnu.foo/tools/base64/encode/hello-worldpipe stdin:
echo "hello world" | curl -d @- gnu.foo/tools/base64/encodehit a tool with no args for its help text:
curl gnu.foo/tools/base64content negotiation
the api detects your client from the User-Agent header:
| client | format |
|---|---|
| curl, wget, httpie | plain text with action hints |
| everything else | hal+json with hypermedia links |
override detection with the accept header or ?json query param:
curl -H "Accept: application/json" gnu.foo/tools
curl gnu.foo/tools?jsonsupported media types: application/json, application/hal+json, application/vnd.hal+json. requesting something else from a non-cli client returns 406.
auth
all read endpoints and tool execution are public — no auth needed.
routes not explicitly public default to requiring authentication via one of:
- api key —
X-API-Keyheader - session — better auth session (cookie or bearer token via
/api/auth)
see authentication for details.
http methods
| method | purpose |
|---|---|
| GET | retrieve resources, browse collections |
| POST | execute tools, create resources |
| PUT | full resource replacement |
| PATCH | partial update |
| DELETE | remove resources |
errors
errors follow rfc 9457 problem details. every error includes a resolvable type uri, status code, and hal _links:
{
"type": "https://api.gnu.foo/errors/not-found",
"title": "not found",
"status": 404,
"detail": "the requested resource does not exist.",
"_links": { "self": { "href": "/tools/nonexistent" } }
}the error type uri resolves to its definition — curl gnu.foo/errors/not-found returns what the error means and an example response.
common status codes:
| status | meaning |
|---|---|
| 400 | bad request — malformed body or missing fields |
| 401 | unauthorized — auth required but not provided |
| 403 | forbidden — insufficient permissions or scopes |
| 404 | not found |
| 406 | not acceptable — unsupported media type |
| 409 | conflict — resource already exists |
| 412 | precondition failed — etag mismatch |
| 429 | rate limit exceeded — check Retry-After header |
| 500 | server error |
conditional requests and caching
the api supports etag-based caching. responses include Cache-Control and ETag headers:
curl -H "If-None-Match: W/\"abc\"" gnu.foo/toolsa 304 Not Modified means nothing changed — use your cached copy.
tips
curl -s gnu.foo/tools | jq # format json
curl -I gnu.foo/tools # headers only
curl -v gnu.foo/tools # verbose