api
Mac API reference
Everything the MCP tools and the CLI do goes through this REST API, so anything that speaks HTTP can drive a Mac.
Terminal
curl -s https://nomac.app/api/v1/me \
-H "Authorization: Bearer $NOMAC_API_KEY"
Basics
- Base URL
https://nomac.app/api/v1 - Auth
Authorization: Bearer nmk_…, with a key from nomac.app/dash/keys,nomac loginorPOST /api-keys. - Errors Always
{ "error": { "code", "message" } }with a meaningful status.402is no credit left (or Mac use paused for the account);422is a failed precondition, such as no Apple connection or invalid input. - Retries Where an endpoint takes an
Idempotency-Key, keep the same key and body when retrying: you get the original operation back, never a second one.
Credit
- $0.90 an hour, charged on each session's ready time in whole minutes, one minute at least.
- Credit comes in $10 packs of 11.1 hours, 1 to 10 at a time, and never expires. There is no subscription and nothing is charged automatically.
GET /mac/credits
- Returns the
creditsleft (spendable, paid, promotional, and reserved, as microdollar strings), thespendable_secondsof Mac time they buy, and recentpurchases.
POST /mac/credits/checkout
- Body
{ "packs": 1-10 }, with a stableIdempotency-Key. - Answers with an
action:open_checkout_urlwith aurlfor the person to pay,check_paymentwhile a payment is verified, orcheckout_ended, with amessagean agent can relay.
Sessions
POST /mac/sessions
- Starts a Mac, with a stable
Idempotency-Key. Answerssession; read it until it isready. With no credit, it answers 402insufficient_creditwith abuy_urlfor the person. - limits
max_duration_seconds(7,200 by default, 28,800 at most),idle_timeout_seconds(600) andspend_cap_microunits($5). - access
prompts: "ask"keeps macOS's usual prompts; by default, the Mac is fully open to the agent, its login password in$NOMAC_MAC_PASSWORD.gatekeeper: "on" | "off". - permissions
{ "com.example.App": ["camera", "microphone"] }or "all": privacy permissions granted at start. - public_key An SSH public key. Leave it out for HTTPS-only access.
- access.drive The drive at
~/drive: left out (or"account"), the account's default, or a new drive of the Mac's own while another Mac has the default; a name, that drive, made empty the first time ("default"is the default itself);"none", no drive. - access.drive_from A drive of the account to copy into the drive made for this Mac (its last save); 404
drive_not_foundif there is none of that name. - reuse With a drive name: when that drive is on a running Mac, answers that Mac (
reused: true) instead ofdrive_in_use. - parallel A second Mac beside the account's running one, for an account that has bought credit.
- queue_seconds 300 to 3,600: wait in line, free, instead of a 409, while the account runs as many Macs as it may, the drive asked for is on another Mac, or no Mac is free...
Drives
GET /mac/drives
- List the account's drives, the default first: name, space used, the Mac using each, recent versions and when each is deleted unused. Up to 10 per account.
GET / DELETE / PATCH /mac/drives/:name
- Reads one drive, empties it (no Mac may be using it; the next Mac that names it gets a new, empty one, and for a drive-N a new drive under a new number), or renames it with
{ "name": "new-name" }(never the default).
GET /mac/sessions
- The account's sessions, to find a Mac again after a lost answer.
GET / DELETE /mac/sessions/:id
- Reads a session, or stops it. Stopping deletes the Mac and every file outside
~/drive; read it untilcleanup_confirmed. Waiting and setup are free; ready time counts, including time between commands.
GET /mac/capabilities
- Supported interfaces and profiles. A session's own
imagelists its macOS, Xcode, Simulator runtimes and tools.
GET / PUT / DELETE /mac/defaults
- What every new Mac starts with:
{ prompts?, gatekeeper?, permissions? }, as a start'saccess.PUTreplaces them andDELETEgoes back to fully open. Answersdefaultsandeffective.
Commands
POST /mac/sessions/:id/jobs?wait=30
- Runs a command, with a stable
Idempotency-Key. Body{ argv: ["/usr/bin/uname", "-a"], cwd?, env?, timeout_seconds? }.
GET /mac/sessions/:id/jobs/:job?wait=30
- Reads a job and, with
wait, waits up to 50 seconds for it to end.
GET /mac/sessions/:id/jobs/:job/output?stream=stdout&cursor=0
- The full output: decode
data_base64and continue atnext_cursor, for stdout and stderr. Up to 8 MiB is kept, and then the last 64 KiB of each stream
Files and links
POST /mac/sessions/:id/files
- Writes a file of up to 3 MiB:
{ path, content? | content_base64?, executable? }.
GET /mac/sessions/:id/files?path=build.log
- Reads a file of up to 3 MiB (
max_bytes):{ path, size, modified_at, truncated, encoding, content | content_base64 }.
Access
GET /mac/sessions/:id/password
- The Mac's login password for this session:
{ user, password, variable }, also$NOMAC_MAC_PASSWORDon the Mac. Each read is audited, and the password is erased when the session ends.
Secrets
GET /secrets
- Names, kinds, where each goes, sizes, delivery and recent activity. Never values.
POST /secrets/requests
{ name, kind, description, destination?, delivery? }. Answers aurlwhere a person enters the value in the browser within 24 hours, so it never passes through a chat.
Signing
GET /apple
- Connected Apple accounts and signing identities every Mac receives, with any notice. Never a key.
POST /apple/signing
{ issuer_id? }. Sets up a distribution identity: an uploaded certificate, the one Apple already issued for NoMac's key, or a new one.