{"openapi":"3.1.0","info":{"title":"Quivvo API","version":"1.0.0","summary":"Create and drive cloud Linux machines for AI agents.","description":"Each machine is a Firecracker microVM with root, Docker and a persistent disk at /data. `id` in a path is a machine id or its name. Every response carries an `x-request-id` header; errors repeat it as `request_id`. Fields a body doesn't need are ignored, not refused. Routes for the dashboard's signed-in session alone, such as /billing, aren't listed."},"servers":[{"url":"https://tryquivvo.com/api/v1"}],"externalDocs":{"url":"https://tryquivvo.com/docs/api","description":"REST API reference"},"security":[{"bearer":[]},{"apiKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key: qvk_..."},"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"The same key, in a header of its own."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Branch on this.","enum":["bad_request","unauthorized","forbidden","not_found","conflict","limit_reached","insufficient_credits","queued","machine_not_running","provider_error","capacity","rate_limited","internal","authorization_pending","access_denied","expired_token"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retry_after_seconds":{"type":["integer","null"]},"docs_url":{"type":"string","description":"What this code means and what to do about it."},"request_id":{"type":"string","description":"Quote this when reporting a problem."},"owner_action":{"type":"object","properties":{"url":{"type":"string"},"message":{"type":"string"}},"required":["url","message"],"description":"Something only the workspace's owner can do, signed in on the dashboard. Pass it on."}},"required":["code","message","retryable","docs_url","request_id"]}},"required":["error"]},"Machine":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"state":{"type":"string","enum":["creating","starting","running","suspending","suspended","stopping","stopped","failed","deleted"]},"template":{"type":"string"},"region":{"type":"string"},"vcpus":{"type":"integer"},"memory_mib":{"type":"integer"},"disk_gib":{"type":"integer"},"url":{"type":["string","null"],"description":"Public URL for the published port. It answers only while the machine runs: a request doesn't wake a suspended machine."},"auto_suspend_minutes":{"type":"integer","description":"0 means never."},"created_at":{"type":"string","format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"last_activity_at":{"type":["string","null"],"format":"date-time"},"error":{"type":["string","null"]},"hourly_cost":{"type":"number","description":"USD per running hour."},"delete_after":{"type":["string","null"],"format":"date-time","description":"When this abandoned machine will be deleted, once its owner has been warned."},"auto_delete_at":{"type":["string","null"],"format":"date-time","description":"When the server deletes this machine, from delete_after_minutes."},"setup":{"type":["object","null"],"description":"The setup script given at create, if any. Its output is the job's logs.","properties":{"state":{"type":"string","enum":["pending","running","succeeded","failed"]},"exit_code":{"type":["integer","null"]},"job_id":{"type":["string","null"]}},"required":["state","exit_code","job_id"]},"suspend_outcome":{"type":["string","null"],"enum":["suspended","stopped",null],"description":"What the last suspend turned into. suspended keeps memory and processes; stopped means the provider couldn't, so only the disk was kept. Cleared on the next boot."},"resume_outcome":{"type":["string","null"],"enum":["resumed","cold_boot",null],"description":"What the last boot came back as: resumed with its memory, or a cold boot with only its disk. Null when it's down, or when the provider didn't say. Also on the answer to any exec or connect that woke the machine."},"warnings":{"type":"array","items":{"type":"string"},"description":"Things that went differently from what you asked. Present only when there are some."}},"required":["id","name","state"]},"Snapshot":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"machine_id":{"type":["string","null"]},"template":{"type":"string"},"disk_gib":{"type":"integer"},"state":{"type":"string","enum":["creating","ready","failed"],"description":"creating: the copy isn't whole yet. Usable once ready."},"created_at":{"type":"string","format":"date-time"},"delete_after":{"type":["string","null"],"format":"date-time"}},"required":["id","name","state"]},"Job":{"type":"object","properties":{"id":{"type":"string"},"cmd":{"type":["string","null"]},"argv":{"type":["array","null"],"items":{"type":"string"}},"cwd":{"type":"string"},"pid":{"type":"integer"},"state":{"type":"string","enum":["running","exited","killed","lost"],"description":"killed with exit_code 124 means it hit its timeout. lost: the process went away and its exit status is unknown, for example after a reboot."},"exit_code":{"type":["integer","null"]},"started_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"timeout_at":{"type":"string","format":"date-time","description":"When it gets killed if it's still running."},"oom_killed":{"type":"boolean","description":"The kernel's OOM killer fired while it ran."}},"required":["id","state"]},"Exec":{"type":"object","properties":{"id":{"type":"string"},"exit_code":{"type":"integer","description":"124 when it hit its timeout, 137 when it was killed, for example out of memory."},"stdout":{"type":"string","description":"At most 1 MiB. Longer output keeps the first 256 KiB and the last 768 KiB, joined by a line saying how many bytes were left out."},"stderr":{"type":"string","description":"Same as stdout."},"truncated":{"type":"boolean"},"timed_out":{"type":"boolean"},"oom_killed":{"type":"boolean","description":"The kernel's OOM killer fired while it ran."},"duration_ms":{"type":"integer"},"resume_outcome":{"type":["string","null"],"enum":["resumed","cold_boot",null],"description":"Only when this command is what woke the machine: whether its memory came back."},"warnings":{"type":"array","items":{"type":"string"},"description":"Things that went differently from what you asked. Present only when there are some."}},"required":["id","exit_code","stdout","stderr"]},"ExecRequest":{"type":"object","properties":{"cmd":{"type":"string","description":"Run with bash -lc. Pass exactly one of cmd or argv."},"argv":{"type":"array","items":{"type":"string"},"description":"Run directly, with no shell."},"cwd":{"type":"string","description":"Defaults to /data/home."},"env":{"type":"object","additionalProperties":{"type":"string"}},"timeout_ms":{"type":"integer","description":"Without background: 280000 by default and at most. With background: one hour by default, at most a day."},"stdin":{"type":"string","description":"Not with background."},"stdin_base64":{"type":"string","description":"Stdin that isn't text, as base64, instead of stdin. Not with background."},"background":{"type":"boolean","description":"Start as a job and return it instead of waiting. If the caller of a waiting command goes away, the command is stopped: SIGTERM, then SIGKILL a few seconds later. A job isn't."},"tail_bytes":{"type":"integer","description":"Return only the last this many bytes of each stream, up to 1 MiB."}},"required":[]},"MachineCreate":{"type":"object","properties":{"name":{"type":"string"},"template":{"type":"string"},"size":{"type":"string","description":"See /catalog. Default medium."},"vcpus":{"type":"integer"},"memory_mib":{"type":"integer"},"disk_gib":{"type":"integer"},"region":{"type":"string","description":"See /catalog. Default ams."},"snapshot":{"type":"string","description":"Start from this snapshot's disk."},"setup":{"type":"string","description":"A bash script run after first boot, up to 64 KB. Follow it in the machine's setup field."},"env":{"type":"object","additionalProperties":{"type":"string"}},"auto_suspend_minutes":{"type":"integer"},"delete_after_minutes":{"type":"integer","description":"The server deletes the machine this long after it's created, whatever state it's in, so a client that dies can't strand one. 1 to 43200."},"idempotency_key":{"type":"string","description":"Same as the Idempotency-Key header."}},"required":[]},"Port":{"type":"object","properties":{"port":{"type":"integer"},"public":{"type":"boolean"},"default":{"type":"boolean"},"url":{"type":["string","null"]},"replaced_port":{"type":["integer","null"],"description":"A machine's URL serves one port, the last published. This is the one it stopped serving."},"warnings":{"type":"array","items":{"type":"string"},"description":"Things that went differently from what you asked. Present only when there are some."}},"required":["port","public"]},"Key":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["user","cli","agent"]},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"}},"required":[]},"HistoryEntry":{"type":"object","properties":{"id":{"type":"string"},"cmd":{"type":["string","null"]},"argv":{"type":["array","null"],"items":{"type":"string"}},"cwd":{"type":["string","null"]},"job_id":{"type":["string","null"]},"exit_code":{"type":["integer","null"],"description":"null if it hasn't finished, or its caller went away."},"timed_out":{"type":"boolean"},"oom_killed":{"type":"boolean"},"cancelled":{"type":"boolean","description":"Its caller went away, so it was stopped."},"started_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}},"required":["id","started_at"]},"ExecOutput":{"type":"object","properties":{"id":{"type":"string"},"job_id":{"type":["string","null"]},"stdout":{"type":["string","null"],"description":"The first 16 KiB and the last 48 KiB of the stream, joined by a line saying how many bytes were left out."},"stderr":{"type":["string","null"]},"truncated":{"type":"boolean"},"exit_code":{"type":["integer","null"]},"timed_out":{"type":"boolean"},"oom_killed":{"type":"boolean"},"cancelled":{"type":"boolean"}},"required":["id"]},"Process":{"type":"object","properties":{"pid":{"type":"integer"},"ppid":{"type":"integer"},"user":{"type":"string"},"command":{"type":"string"},"rss_bytes":{"type":"integer"},"cpu_seconds":{"type":"number"},"started_at":{"type":"string","format":"date-time"}},"required":["pid","command"]},"MachineStatus":{"type":"object","properties":{"version":{"type":"string"},"machine_id":{"type":"string"},"uptime_seconds":{"type":"integer"},"idle_seconds":{"type":"integer"},"sessions":{"type":"integer"},"jobs_running":{"type":"integer"},"load1":{"type":"number"},"memory":{"type":"object","properties":{"total_bytes":{"type":"integer"},"used_bytes":{"type":"integer"}},"required":[]},"data_disk":{"type":"object","properties":{"total_bytes":{"type":"integer"},"used_bytes":{"type":"integer"}},"required":[]},"oom_kills":{"type":"integer"},"last_oom":{"type":["string","null"],"format":"date-time"}},"required":["idle_seconds","sessions","jobs_running"]},"ProviderEvent":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"type":{"type":"string"},"status":{"type":["string","null"]},"exit_code":{"type":["integer","null"]},"oom_killed":{"type":"boolean"}},"required":["at","type"]},"MachineLogs":{"type":"object","properties":{"machine":{"type":"string"},"name":{"type":"string"},"state":{"type":"string"},"error":{"type":["string","null"]},"logs":{"type":["string","null"],"description":"Boot and daemon logs. null unless the machine is running."},"events":{"type":"array","items":{"$ref":"#/components/schemas/ProviderEvent"},"description":"What the provider recorded, when the machine can't be asked."},"note":{"type":["string","null"]}},"required":["machine","state","logs","events"]},"Plan":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"price":{"type":"number"},"monthly_credits":{"type":"number"},"signup_credits":{"type":"number"},"max_running":{"type":"integer"},"max_machines":{"type":"integer"},"max_vcpus":{"type":"integer"},"max_memory_mib":{"type":"integer"},"max_disk_gib":{"type":"integer"},"max_snapshots":{"type":["integer","null"]},"max_auto_suspend_minutes":{"type":["integer","null"]},"blurb":{"type":"string"}},"required":[]},"ExecLimits":{"type":"object","properties":{"sync_default_seconds":{"type":"integer"},"sync_max_seconds":{"type":"integer"},"job_default_seconds":{"type":"integer"},"job_max_seconds":{"type":"integer"}},"required":[]},"Catalog":{"type":"object","properties":{"templates":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"default":{"type":"boolean"}},"required":[]}},"sizes":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"vcpus":{"type":"integer"},"memory_mib":{"type":"integer"},"default":{"type":"boolean"}},"required":[]}},"regions":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"default":{"type":"boolean"}},"required":[]}},"plans":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}},"rates":{"type":"object","properties":{"vcpu_hour":{"type":"number"},"memory_gib_hour":{"type":"number"},"disk_gib_month":{"type":"number"},"included_disk_gib":{"type":"number"}},"required":[]},"topups":{"type":"array","items":{"type":"number"}},"exec":{"$ref":"#/components/schemas/ExecLimits"},"queue_open":{"type":"boolean","description":"Whether a new sign-up waits in the queue before it can create machines."}},"required":[]},"Usage":{"type":"object","properties":{"period_start":{"type":"string","format":"date-time"},"period_end":{"type":"string","format":"date-time"},"plan":{"type":"string"},"credit_balance":{"type":"number"},"cost_this_period":{"type":"number"},"machines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deleted":{"type":"boolean"},"running_seconds":{"type":"integer"},"cost":{"type":"number"}},"required":[]}},"snapshots":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"deleted":{"type":"boolean"},"cost":{"type":"number"}},"required":[]}},"days":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"cost":{"type":"number"}},"required":[]}},"rates":{"type":"object","properties":{"vcpu_hour":{"type":"number"},"memory_gib_hour":{"type":"number"},"disk_gib_month":{"type":"number"},"included_disk_gib":{"type":"number"}},"required":[]}},"required":[]},"Whoami":{"type":"object","properties":{"kind":{"type":"string","enum":["session","user","cli","agent"]},"key":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"}},"description":"null for a dashboard session."},"email":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"workspace":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"plan":{"type":"string"},"plan_status":{"type":"string"},"credit_balance":{"type":"number"}},"required":[]},"limits":{"type":"object","properties":{"max_running":{"type":"integer"},"max_machines":{"type":"integer"},"max_vcpus":{"type":"integer"},"max_memory_mib":{"type":"integer"},"max_disk_gib":{"type":"integer"},"max_snapshots":{"type":["integer","null"]},"max_auto_suspend_minutes":{"type":["integer","null"]}},"required":[]},"exec":{"$ref":"#/components/schemas/ExecLimits"},"machines":{"type":"object","properties":{"total":{"type":"integer"},"running":{"type":"integer"}},"required":[]},"queue":{"$ref":"#/components/schemas/QueueState"}},"required":["kind","scopes","workspace","limits"]},"QueueState":{"type":"object","properties":{"waiting":{"type":"boolean","description":"False means nothing below is present, and this workspace can create machines."},"position":{"type":"integer"},"invites":{"type":"integer","description":"People who signed up with the link and counted."},"moves_per_invite":{"type":"integer"},"max_counted_invites":{"type":"integer"},"invite_url":{"type":"string","description":"For the workspace's owner to pass on. Each person who signs up with it moves this workspace up."}},"required":["waiting"]},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"}},"required":[]}}},"paths":{"/catalog":{"get":{"operationId":"getCatalog","summary":"Templates, sizes, regions, plans, prices and exec limits.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Catalog"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/whoami":{"get":{"operationId":"whoami","summary":"What this key or session is and may do: kind, scopes, workspace, plan limits. Needs no scope.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Whoami"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/queue":{"get":{"operationId":"getQueue","summary":"This workspace's place in the queue and its invite link. Needs no scope.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueueState"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/feedback":{"post":{"operationId":"sendFeedback","summary":"Report a problem to Quivvo: a message, optionally the machine and any context that helps.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Up to 4000 bytes."},"machine":{"type":"string","description":"A machine's name or id."},"context":{"type":"object","description":"Any JSON, up to 16 KiB. A request_id is useful."}},"required":["message"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"received":{"type":"boolean"}},"required":["id","received"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines":{"get":{"operationId":"listMachines","summary":"List machines.","x-required-scope":"machines:read","parameters":[{"name":"state","in":"query","required":false,"description":"Only machines in this state.","schema":{"type":"string"}},{"name":"all","in":"query","required":false,"description":"1 to include deleted machines.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"machines":{"type":"array","items":{"$ref":"#/components/schemas/Machine"}}},"required":["machines"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createMachine","summary":"Create a machine. Answers once the provider has accepted it, with state starting. A workspace can create 60 an hour for each machine its plan runs at once.","x-required-scope":"machines:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}},{"name":"wait","in":"query","required":false,"description":"1 to wait until it's running.","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MachineCreate"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}":{"get":{"operationId":"getMachine","summary":"Read a machine.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateMachine","summary":"Rename, change auto-suspend or the delete deadline, or resize. CPU and memory only while stopped; disks only grow.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"auto_suspend_minutes":{"type":"integer"},"vcpus":{"type":"integer"},"memory_mib":{"type":"integer"},"disk_gib":{"type":"integer"},"delete_after_minutes":{"type":["integer","null"],"description":"From now. null cancels it. A deadline sooner than the current one, or a first one, also needs the machines:delete scope."}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteMachine","summary":"Delete a machine and its disk. Repeating it succeeds.","x-required-scope":"machines:delete","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"X-Confirm-Delete","in":"header","required":true,"description":"The exact name or id of what you're deleting.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"already_deleted":{"type":"boolean","description":"This machine was gone already: repeating a delete succeeds."}},"required":["deleted"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/start":{"post":{"operationId":"startMachine","summary":"Boot a stopped machine.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}},{"name":"wait","in":"query","required":false,"description":"0 to answer before the machine is ready.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/stop":{"post":{"operationId":"stopMachine","summary":"Shut a machine down. Files stay; memory and processes are lost.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/suspend":{"post":{"operationId":"suspendMachine","summary":"Pause a machine. Memory and processes are kept when the provider can do it (on Fly that's documented up to 2 GB); otherwise it's stopped instead, which also counts as success. suspend_outcome says which happened.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/resume":{"post":{"operationId":"resumeMachine","summary":"Wake a suspended machine. resume_outcome says whether memory came back or it was a cold boot.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}},{"name":"wait","in":"query","required":false,"description":"0 to answer before the machine is ready.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/restart":{"post":{"operationId":"restartMachine","summary":"Power-cycle a machine.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}},{"name":"wait","in":"query","required":false,"description":"0 to answer before the machine is ready.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/exec":{"post":{"operationId":"execInMachine","summary":"Run a command. Send Accept: text/event-stream to stream stdout, stderr and exit events. Commands that wait stop at 280 seconds; longer work goes in a background job.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Exec"},{"type":"object","properties":{"job":{"$ref":"#/components/schemas/Job"}},"required":["job"]}]}},"text/event-stream":{"schema":{"type":"string","description":"Events stdout and stderr ({data}, and data_base64 with the real bytes when a chunk isn't valid UTF-8) and a last one, exit ({id, exit_code, timed_out, oom_killed, duration_ms})."}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/jobs":{"get":{"operationId":"listJobs","summary":"List background jobs.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/Job"}}},"required":["jobs"]}}},"headers":{"X-Quivvo-Woke":{"description":"Only when this read is what woke the machine, restarting its bill: whether its memory came back.","schema":{"type":"string","enum":["resumed","cold_boot"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/jobs/{job}":{"get":{"operationId":"getJob","summary":"Read a job.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"job","in":"path","required":true,"description":"Job id.","schema":{"type":"string"}},{"name":"wait","in":"query","required":false,"description":"Seconds to wait for it to finish, up to 280. Ask again if it's still running.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/jobs/{job}/logs":{"get":{"operationId":"getJobLogs","summary":"A job's output.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"job","in":"path","required":true,"description":"Job id.","schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"description":"Bytes to skip.","schema":{"type":"integer"}},{"name":"tail_bytes","in":"query","required":false,"description":"Only the last this many bytes.","schema":{"type":"integer"}},{"name":"follow","in":"query","required":false,"description":"1 to stream until the job ends, or for about 280 seconds. If it's still running, follow on from the bytes you got so far.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"string"}}},"headers":{"X-Next-Offset":{"description":"Where the next read starts. Not sent with follow.","schema":{"type":"integer"}},"X-Quivvo-Woke":{"description":"Only when this read is what woke the machine, restarting its bill: whether its memory came back.","schema":{"type":"string","enum":["resumed","cold_boot"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/jobs/{job}/kill":{"post":{"operationId":"killJob","summary":"Signal a job.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"job","in":"path","required":true,"description":"Job id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"signal":{"type":"string","enum":["TERM","KILL","INT"]}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/history":{"get":{"operationId":"getHistory","summary":"Past commands, newest first. Works while the machine is stopped.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"How many, 100 by default.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"history":{"type":"array","items":{"$ref":"#/components/schemas/HistoryEntry"}}},"required":["history"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/history/{exec}/output":{"get":{"operationId":"getExecOutput","summary":"A past command's output: the start and end of each stream.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"exec","in":"path","required":true,"description":"Command id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecOutput"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/ps":{"get":{"operationId":"listProcesses","summary":"Running processes. Doesn't wake the machine.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"processes":{"type":"array","items":{"$ref":"#/components/schemas/Process"}}},"required":["processes"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/status":{"get":{"operationId":"getMachineStatus","summary":"What the machine's daemon reports: idle time, sessions, memory, disk. Doesn't wake the machine.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MachineStatus"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/logs":{"get":{"operationId":"getMachineLogs","summary":"Boot and daemon logs of a running machine. Never wakes a machine: for any other state the answer has its state, error and the provider's events.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"lines","in":"query","required":false,"description":"How many lines.","schema":{"type":"integer"}},{"name":"format","in":"query","required":false,"description":"json for the structured form, as does Accept: application/json.","schema":{"type":"string","enum":["json"]}}],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"string"}},"application/json":{"schema":{"$ref":"#/components/schemas/MachineLogs"}}},"headers":{"X-Machine-State":{"description":"On the text form.","schema":{"type":"string"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/files":{"get":{"operationId":"readFile","summary":"A directory listing (JSON), or a file's bytes.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"path","in":"query","required":true,"description":"Absolute, or relative to /data/home.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string"},"entries":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string","enum":["file","dir","symlink","other"]},"size":{"type":"integer"},"mode":{"type":"string"},"mtime":{"type":"string"}},"required":[]}}},"required":[]}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}},"headers":{"X-Quivvo-Woke":{"description":"Only when this read is what woke the machine, restarting its bill: whether its memory came back.","schema":{"type":"string","enum":["resumed","cold_boot"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"writeFile","summary":"Write the raw body to a file, up to 4 MB. Bigger files go straight to the machine with connect.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"path","in":"query","required":true,"description":"Where to write.","schema":{"type":"string"}},{"name":"mode","in":"query","required":false,"description":"For example 0644.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string"},"size":{"type":"integer"}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteFile","summary":"Delete a file or directory.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"path","in":"query","required":true,"description":"What to delete.","schema":{"type":"string"}},{"name":"recursive","in":"query","required":false,"description":"1 for directories.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/connect":{"post":{"operationId":"connectToMachine","summary":"A 15-minute token for the daemon inside the machine: terminal, TCP tunnels, large files. The CLI is the supported client for what it opens. Wakes the machine.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"token":{"type":"string"},"expires_at":{"type":"string"},"machine":{"$ref":"#/components/schemas/Machine"}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/ports":{"get":{"operationId":"listPorts","summary":"Published ports.","x-required-scope":"machines:read","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ports":{"type":"array","items":{"$ref":"#/components/schemas/Port"}}},"required":["ports"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"publishPort","summary":"Publish a port on the machine's URL. It serves one port, the last published. The URL doesn't wake a suspended machine.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"port":{"type":"integer"},"public":{"type":"boolean","description":"false for a token-gated link."}},"required":["port"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Port"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/ports/{port}":{"delete":{"operationId":"unpublishPort","summary":"Unpublish a port.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"port","in":"path","required":true,"description":"Port number.","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/snapshots":{"post":{"operationId":"saveSnapshot","summary":"Save a copy of the machine's disk. Answers creating if the copy takes longer than about a minute; it's usable once ready.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Snapshot"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/restore":{"post":{"operationId":"restoreMachine","summary":"Put a snapshot's disk back on this machine; same id, name and URL. limit_reached means nothing changed. If something takes the running slot in between, the answer is the machine, stopped, with warnings.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"snapshot":{"type":"string"}},"required":["snapshot"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Machine"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/machines/{id}/fork":{"post":{"operationId":"forkMachine","summary":"Copy this machine's disk into new machines (not its memory). Each one stands alone: those that couldn't be made are listed in failed. Only if none could is the answer an error.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Machine id or name.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Repeating a request with the same key within 24 hours returns the first response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"name":{"type":"string"}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"machines":{"type":"array","items":{"$ref":"#/components/schemas/Machine"}},"failed":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"retry_after_seconds":{"type":["integer","null"]}},"required":[]}},"required":["name","error"]}}},"required":["machines","failed"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/snapshots":{"get":{"operationId":"listSnapshots","summary":"List snapshots.","x-required-scope":"machines:read","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"snapshots":{"type":"array","items":{"$ref":"#/components/schemas/Snapshot"}}},"required":["snapshots"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/snapshots/{id}":{"delete":{"operationId":"deleteSnapshot","summary":"Delete a snapshot. Repeating it succeeds.","x-required-scope":"machines:delete","parameters":[{"name":"id","in":"path","required":true,"description":"Snapshot id or name.","schema":{"type":"string"}},{"name":"X-Confirm-Delete","in":"header","required":true,"description":"The exact name or id of what you're deleting.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"already_deleted":{"type":"boolean","description":"This snapshot was gone already: repeating a delete succeeds."}},"required":["deleted"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/usage":{"get":{"operationId":"getUsage","summary":"This month's cost by machine and day, and the credit balance.","x-required-scope":"machines:read","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/keys":{"get":{"operationId":"listKeys","summary":"List API keys.","x-required-scope":"keys:write","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/Key"}}},"required":["keys"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createKey","summary":"Create an API key. The secret is shown once.","x-required-scope":"keys:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}},"required":["name"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/Key"},"api_key":{"type":"string"}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/keys/{id}":{"delete":{"operationId":"revokeKey","summary":"Revoke an API key. Any key can revoke itself; revoking another takes keys:write.","parameters":[{"name":"id","in":"path","required":true,"description":"Key id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/device":{"post":{"operationId":"startDeviceSignIn","summary":"Start a sign-in for the CLI or an agent with no browser.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["cli","agent"]},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"device_code":{"type":"string"},"user_code":{"type":"string"},"verification_url":{"type":"string"},"verification_url_complete":{"type":"string"},"expires_in":{"type":"integer"},"interval":{"type":"integer"}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/device/token":{"post":{"operationId":"pollDeviceSignIn","summary":"Poll until approved. Errors with authorization_pending until then. Asking again within 10 minutes of the answer, if it got lost, returns a new key and revokes the first.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"device_code":{"type":"string"}},"required":["device_code"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string"},"key":{"$ref":"#/components/schemas/Key"},"workspace":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":[]}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/device/request":{"get":{"operationId":"getDeviceSignIn","summary":"What a sign-in asks for, for whoever is deciding on it. A sign-in that was approved past its expiry and never fetched has expired.","x-required-scope":"keys:write","parameters":[{"name":"code","in":"query","required":true,"description":"The code the device shows, such as ABCD-EFGH.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user_code":{"type":"string"},"kind":{"type":"string","enum":["cli","agent"]},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["pending","approved","denied"]},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"started_from":{"type":["string","null"]}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/device/approve":{"post":{"operationId":"approveDeviceSignIn","summary":"Approve a pending sign-in.","x-required-scope":"keys:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"user_code":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}},"required":["user_code"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"approved":{"type":"boolean"},"name":{"type":"string"},"kind":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/device/deny":{"post":{"operationId":"denyDeviceSignIn","summary":"Refuse a pending sign-in.","x-required-scope":"keys:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"user_code":{"type":"string"}},"required":["user_code"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"approved":{"type":"boolean"},"name":{"type":"string"},"kind":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"get":{"operationId":"listWebhooks","summary":"List webhooks.","x-required-scope":"machines:read","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}},"required":["webhooks"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createWebhook","summary":"Register a webhook. The signing secret is shown once.","x-required-scope":"machines:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["machine.ready","machine.suspended","machine.stopped","machine.failed","machine.deleted"]}}},"required":["url"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/Webhook"},"secret":{"type":"string"}},"required":["webhook","secret"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}":{"delete":{"operationId":"deleteWebhook","summary":"Delete a webhook.","x-required-scope":"machines:write","parameters":[{"name":"id","in":"path","required":true,"description":"Webhook id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":[]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}