A Mac per user
macOS Platform gives every user of your product a cloud Mac of their own: macOS with Xcode, their own drive, and none of your account's secrets. Your backend starts it by your user's id, shows it to them, and hears when it ends.
Start a Mac for your user
import { NoMac } from "@nomac/sdk";
const nomac = new NoMac(); // NOMAC_API_KEY
const mac = await nomac.macs.start({ label: user.id, reuse: true });
await mac.waitUntilReady();
const { stdout } = await mac.run("xcodebuild -version");
const { url } = await mac.viewLink({ control: true }); // for your user
const { token } = await mac.token(); // for their agentMake the API key at nomac.app/dash/keys and keep it on your server: it starts and stops Macs for the whole account. Your user gets a link or a token for their own Mac only. A Mac is usually ready in about 30 seconds.
A label per user
label is your user's id: up to 64 letters, digits and . _ : @ -. What NoMac keeps for a user belongs to their label.
- Their drive
- Their files and build cache at
~/drive, back on their next Mac. See Drives and data. - Their Macs
reuse: trueanswers the user's starting or running Mac instead of a second one, andmacs.list({ label })lists theirs with their cost.- No secrets of yours
- None of your account's secrets, signing or drives go on a user's Mac. Their agent puts its own keys and files there.
Billing records keep the label, so use your own user id, not an email. Keep your users on a NoMac account of their own, apart from your team's: any key of an account reaches every Mac of that account by its id.
What their Mac has
- The same Mac as any NoMac session: macOS with Xcode, sudo with no password, the login password in
$NOMAC_MAC_PASSWORD, prompts answered, the screen never locked. - Only what is under
~/driveis kept when it stops; the rest of the Mac is deleted. - No App Store calls with your Apple account: signing and TestFlight stay on your own Macs.
How long it runs
There is no session time limit. Each Mac stops at its own limits: max_duration_seconds (2 hours unless you set more), its spend cap ($5 unless you set more, about 5 hours 33 minutes) and its idle timeout (10 minutes without a command, SSH or input; watching does not count). mac.extend({ minutes }) raises the time and the spend cap while it runs, and mac.ending_soon tells you 10 minutes before a stop.
Start it over REST
curl -X POST https://nomac.app/api/v1/mac/sessions \
-H "authorization: Bearer $NOMAC_API_KEY" -H "idempotency-key: start-user-42-1" \
-H "content-type: application/json" \
-d '{"label": "user-42", "reuse": true, "require_drive": true, "queue_seconds": 900,
"limits": {"max_duration_seconds": 28800, "spend_cap_microunits": "10000000"}}'- label
- Your user's id. The Mac gets their drive, made empty the first time.
- reuse
- With a label: the user's starting or running Mac is the answer (reused: true).
- require_drive
- The start ends (mac.ended, drive_unavailable, nothing charged) rather than run without the user's drive.
- queue_seconds
- Wait in line, free, up to this long (300 to 3,600) when no Mac is free or your account runs its most at once.
- limits
- max_duration_seconds, spend_cap_microunits (USD × 1,000,000) and idle_timeout_seconds.
How many at once
An account runs one Mac at a time until we raise it: tell us how many your users need. Your users' Macs come from NoMac's shared pool and start only while one Mac there stays free for other sessions, so at busy hours a start without queue_seconds answers capacity_unavailable. With it, the start waits in line, free.
The rest of the platform
- Show the desktop
- Watch and control links with no sign-in, the embed, and a token for one Mac.
- Drives and data
- Each user's drive, its price, and one call that deletes a user.
- Webhooks and billing
- Signed events when a Mac is ready, ending and ended, with the label and the cost.
Price
The Macs are NoMac Session's, at its price: $0.90 an hour per Mac, billed per minute from the account's prepaid credit, one minute at least. Waiting in line is free.