Skip to content
GurtOS

Overview

Tasks, approvals, the action log, pairing and apps on one box.

The box’s HTTP API is how the portal, a phone and outside tools list tasks, start them, answer approvals, undo work and follow the action log. These pages are generated from the routes the core serves. For a guided overview, read HTTP API.

Base address

http://127.0.0.1:7700/api. Every route also answers without the /api prefix, so http://127.0.0.1:7700/tasks and http://127.0.0.1:7700/api/tasks are the same route. The same API is served on the Unix socket BOX_HOME/api.sock (root only).

Format

Requests and responses are JSON. Send content-type: application/json with a body. A body that is not valid JSON is a 400. A body over 10 MB is a 413, and over 1 MB on the routes that need no token. A failed request returns a JSON object with one field, error. Bad input, an unknown task field and an id that does not exist are 400. A missing, unknown or revoked device token is 401. An owner’s route called by anyone else is 403. An unknown route is 404. A request that clashes with the box’s state is 409. Too many wrong pairing codes are 429.

Who may call what

A request from the box itself (over the Unix socket, or from 127.0.0.1 or ::1 with no proxy header such as X-Forwarded-For, Forwarded, X-Real-IP, X-Forwarded-Host or Tailscale-User-Login, a Host of 127.0.0.1, localhost or [::1], and no Origin except the box’s own address) is the box’s own screen and needs no token. A helper on the box that runs as nobody or as a task user may read, start tasks and answer approvals like the screen, but never uses the owner’s routes.

Every other request must carry a paired device’s token, as Authorization: Bearer <token> or ?access_token=<token>. Without one the answer is 401. Open without a token: GET /health (a short answer), POST /pair, the work-account sign-in routes under /sso, and the portal’s own pages.

An app’s page, served at /t/<app>/, is sandboxed and gets a window token from POST /apps/{id}/window instead. That token reaches only the app’s own routes, GET /tasks, GET /tasks/{id}, GET /approvals, and answers to the app’s own requests. Anything else is 403.

Some routes are the owner’s: pairing codes and devices, setup, settings, app permissions, the vault, apps on and off, the owner, folders on a task, Keep and Undo Keep, remote access and Quick Start. From outside the box they need a device that was paired as the owner, else 403. On a GurtOS Business box, people, the policy and the kill switch are for an admin or the owner, and the audit is for an auditor, an admin or the owner.

The box listens on 127.0.0.1 by default. BOX_LISTEN changes the address.

Cross-origin requests

The portal is served from the same address as the API and needs no CORS. The GurtOS web app’s origin (BOX_APP, https://app.gurtos.com by default) is always allowed. A browser app on another origin needs BOX_ORIGINS (a comma-separated list of origins, or *) in the box’s environment. A sandboxed app page has the origin null, which is allowed too. The box allows the content-type, authorization and x-box-person request headers. A token is required either way.

Remote access

The remote access, push and Quick Start routes work against a relay. A hosted relay is not running during the preview, so point the box at a relay you run, with BOX_RELAY or PUT /remote/relay.

Not under /api

App routes are served at /t/<app>/... and webhooks at /hook/<app>/<name>. Neither answers under the /api prefix. Every HTML or XML answer from an app route carries Content-Security-Policy: sandbox without allow-same-origin, so the page has no origin of its own.

Information

A paired device’s token from POST /pair. Required from outside the box on every route but GET /health, POST /pair and the /sso sign-in routes. Requests from the box itself need none.

Security scheme type: http

The same device token as a query parameter, for clients that cannot send headers, such as a browser’s EventSource on /log/stream.

Security scheme type: apiKey

Query parameter name: access_token