Build with Graspable

The local API

The HTTP API of the Graspable agent on your computer. Access tokens and their levels, and the requests for projects, files and runs.

The Graspable app talks to its agent over an HTTP API on your computer. Scripts and other programs can use the same API. It listens on 127.0.0.1 only.

For most uses the grasp command or the MCP server is simpler. Use the API when you want to build your own tool.

Address and access

grasp api
# http://127.0.0.1:51877

The port changes each time the agent starts, so ask for the address each time, or read it from ~/.graspable/agent/api.json.

Every request needs Authorization: Bearer <token>. Create a token in Settings → Plugins and connectors → Access tokens, or:

grasp token create "my script" --scope run

The token is shown once. Graspable stores only a hash of it.

Level May
read Look at projects, files, runs and usage
run Also create projects, edit files, start and steer runs, answer approvals, start previews, use memory
admin Also change plugins, skills, components, sign-ins and tokens, move projects to the cloud, delete projects

A request above the token's level is answered with 403.

Projects and files

Request Does
GET /projects List projects
POST /projects { "name", "template" } Create a project. Packages install in the background; install becomes done
GET /projects/:id One project
GET /projects/:id/files File paths
GET /projects/:id/file?path=App.jsx { "path", "content" }
PUT /projects/:id/file { "path", "content" } Write a file
POST /projects/:id/preview Start the preview: { "url", "port" }
DELETE /projects/:id/preview Stop the preview
POST /projects/:id/check Build and load in a headless browser: { "pass", "build", "browser" }

Paths are relative to the project. Paths that leave the project are refused.

Runs

POST /runs starts a run and returns { "runId" }:

{
  "projectId": "3f9a12bc",
  "prompt": "Add a floor that reflects the planets.",
  "engine": "claude-code",
  "approvalPolicy": "guarded"
}
Field Meaning
engine claude-code or codex (their own sign-in on this computer), or pi (the Graspable agent)
provider For pi: { "provider": "anthropic", "modelId": "…", "apiKey": "…" }. For the others, optionally { "provider": "<engine>", "modelId": "…" }
approvalPolicy auto, guarded (default) or strict
budget { "maxCostUsd", "maxTokens" }: the run stops when either is passed
plugins Secret fields of switched-on plugins: { "<plugin>": { "<FIELD>": "…" } }
Request Does
GET /runs?projectId=:id Runs of a project
GET /runs/:id { "state", "events" }
GET /runs/:id/events?since=<seq> The same events as a stream (server-sent events) until the run is finished
POST /runs/:id/approve { "toolCallId", "approved" } Answer an approval request
POST /runs/:id/steer { "text" } Send the agent a message while it works
POST /runs/:id/cancel Stop the run
POST /runs/:id/revert Undo the run's file changes

A run's state is running, waiting_user, completed, failed or cancelled.

Events

Each event is { "runId", "seq", "ts", "event" }. The kinds you will use most:

event.type Meaning
text The agent said something
tool_call, tool_result A step and its result
approval_required The run waits for an answer. Send toolCallId to /approve
fragment_update A file was written: filePath, code
verification A check finished: kind (build, smoke, xr), pass, summary
completion The end: status (success, failure, cancelled) and summary

An example

API=$(grasp api | head -1)
TOKEN=<your token>
curl -s -X POST "$API/runs" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"projectId":"3f9a12bc","prompt":"Make the sun pulse slowly.","engine":"codex"}'