openapi: 3.1.0
info:
title: Fly.io Machines API
description: >-
The Fly.io Machines API is a low-level REST interface for provisioning and
managing Fly Machines, which are fast-booting virtual machines that run on
Fly.io's global edge infrastructure. It provides endpoints for creating,
starting, stopping, and destroying Machines, as well as managing Fly Apps,
Fly Volumes, and TLS certificates. The API is accessible publicly at
https://api.machines.dev or internally within the Fly.io private WireGuard
network at http://_api.internal:4280. All requests require bearer token
authentication using a Fly.io API token, which can be obtained via the
flyctl CLI.
version: 'v1'
contact:
name: Fly.io Support
url: https://fly.io/docs/machines/api/
termsOfService: https://fly.io/legal/terms-of-service/
externalDocs:
description: Fly.io Machines API Documentation
url: https://fly.io/docs/machines/api/
servers:
- url: https://api.machines.dev
description: Public Production Server
- url: http://_api.internal:4280
description: Internal WireGuard Network Server
tags:
- name: Apps
description: >-
Operations for creating, listing, and deleting Fly Apps. Every Fly Machine
belongs to a Fly App, which groups related Machines together.
- name: Machines
description: >-
Core operations for creating, reading, updating, starting, stopping,
suspending, and deleting Fly Machines. Machines are fast-booting virtual
machines deployed on Fly.io's global edge infrastructure.
- name: Tokens
description: >-
Operations for requesting OpenID Connect (OIDC) tokens from third-party
services, enabling Fly Machines to authenticate to external systems using
workload identity.
- name: Volumes
description: >-
Operations for managing persistent storage volumes that can be attached to
Fly Machines. Volumes provide durable block storage that persists across
Machine restarts.
security:
- bearerAuth: []
paths:
/v1/apps:
get:
operationId: listApps
summary: List apps in an organization
description: >-
Returns a list of all Fly Apps belonging to the specified organization.
Results include the app name, machine count, volume count, and network
configuration for each app.
tags:
- Apps
parameters:
- $ref: '#/components/parameters/orgSlug'
responses:
'200':
description: A list of apps in the organization.
content:
application/json:
schema:
type: object
properties:
total_apps:
type: integer
description: Total number of apps in the organization.
apps:
type: array
description: Array of app objects.
items:
$ref: '#/components/schemas/App'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createApp
summary: Create a Fly App
description: >-
Creates a new Fly App under the specified organization. An app is a
logical grouping of Fly Machines that share a name, network, and
routing configuration. Machines must belong to an app before they
can be created.
tags:
- Apps
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAppRequest'
responses:
'201':
description: App created successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/App'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/v1/apps/{app_name}:
get:
operationId: getApp
summary: Get a Fly App
description: >-
Retrieves details about a specific Fly App by its name, including
the app status, organization, and associated network configuration.
tags:
- Apps
parameters:
- $ref: '#/components/parameters/appName'
responses:
'200':
description: App details.
content:
application/json:
schema:
$ref: '#/components/schemas/App'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteApp
summary: Delete a Fly App
description: >-
Permanently deletes a Fly App and all of its associated Machines,
volumes, and IP addresses. This operation is irreversible. Use the
force query parameter to stop all running Machines before deletion.
tags:
- Apps
parameters:
- $ref: '#/components/parameters/appName'
- name: force
in: query
description: >-
When true, all running Machines in the app are stopped before
deletion proceeds. Without this flag, deletion fails if any
Machines are running.
required: false
schema:
type: boolean
responses:
'202':
description: App deletion accepted.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/machines:
get:
operationId: listMachines
summary: List machines in an app
description: >-
Returns a list of all Fly Machines belonging to the specified app,
including their current state, region, configuration, and private IP
addresses.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
responses:
'200':
description: A list of machines in the app.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Machine'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: createMachine
summary: Create a Fly Machine
description: >-
Creates and optionally starts a new Fly Machine within the specified
app. The only required configuration field is the container image path.
Additional configuration controls compute resources, networking,
environment variables, health checks, mounts, and restart policies.
Machines are private by default; expose them publicly by allocating
an IP address and configuring services with port handlers.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateMachineRequest'
responses:
'200':
description: Machine created successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/Machine'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/v1/apps/{app_name}/machines/{machine_id}:
get:
operationId: getMachine
summary: Get a Fly Machine
description: >-
Retrieves the current state and full configuration of a specific Fly
Machine by its ID, including its instance ID, private IP, region,
and applied configuration object.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
responses:
'200':
description: Machine details.
content:
application/json:
schema:
$ref: '#/components/schemas/Machine'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: updateMachine
summary: Update a Fly Machine
description: >-
Updates the configuration of an existing Fly Machine. The Machine
is updated in place and a new instance_id is assigned upon successful
update. The same configuration schema used for creation applies here.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateMachineRequest'
responses:
'200':
description: Machine updated successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/Machine'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteMachine
summary: Delete a Fly Machine
description: >-
Permanently destroys a Fly Machine. The Machine must be in a stopped
or suspended state before it can be deleted. Once deleted, the Machine
and its ephemeral disk are gone; only attached volumes persist.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
responses:
'200':
description: Machine deleted successfully.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/machines/{machine_id}/start:
post:
operationId: startMachine
summary: Start a Fly Machine
description: >-
Starts a stopped or suspended Fly Machine. The Machine boots from
its current configuration and transitions to the started state.
This endpoint returns immediately; use the wait endpoint to block
until the Machine reaches the started state.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
responses:
'200':
description: Machine start initiated.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/machines/{machine_id}/stop:
post:
operationId: stopMachine
summary: Stop a Fly Machine
description: >-
Stops a running Fly Machine by sending a signal to its init process.
The Machine transitions to the stopped state. By default, SIGINT is
sent; use the signal and timeout fields to customize graceful shutdown
behavior.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
signal:
type: string
description: >-
Signal to send to the Machine's init process. Defaults
to SIGINT.
example: SIGTERM
timeout:
type: integer
description: >-
Seconds to wait for the Machine to stop gracefully before
forcing termination.
example: 30
responses:
'200':
description: Machine stop initiated.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/machines/{machine_id}/suspend:
post:
operationId: suspendMachine
summary: Suspend a Fly Machine
description: >-
Suspends a running Fly Machine by taking a memory snapshot and halting
execution. Suspended Machines can be resumed quickly because they
restore from the snapshot rather than booting from scratch. This
enables very fast wake times for workloads that are idle.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
responses:
'200':
description: Machine suspension initiated.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/machines/{machine_id}/wait:
get:
operationId: waitForMachineState
summary: Wait for a Machine to reach a state
description: >-
Blocks until the specified Fly Machine reaches the desired state,
or until the timeout elapses. Use this endpoint after starting,
stopping, or suspending a Machine to confirm the state transition
has completed before proceeding.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
- name: state
in: query
description: >-
The target Machine state to wait for. Valid values are started,
stopped, suspended, and destroyed.
required: false
schema:
type: string
enum: [started, stopped, suspended, destroyed]
- name: timeout
in: query
description: >-
Maximum number of seconds to wait for the state transition.
Defaults to 60 seconds.
required: false
schema:
type: integer
minimum: 1
maximum: 300
- name: instance_id
in: query
description: >-
Wait for a specific Machine instance version to reach the target
state. Use the instance_id from a Machine update response to
confirm that particular deployment is live.
required: false
schema:
type: string
responses:
'200':
description: Machine reached the desired state.
'408':
description: Timeout elapsed before the Machine reached the desired state.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/machines/{machine_id}/cordon:
post:
operationId: cordonMachine
summary: Cordon a Fly Machine
description: >-
Marks a Fly Machine as cordoned, which removes it from load balancer
rotation so it stops receiving new traffic. Existing connections are
not interrupted. Use this endpoint for blue-green deployments or when
draining a Machine before maintenance.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
responses:
'200':
description: Machine cordoned successfully.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/machines/{machine_id}/uncordon:
post:
operationId: uncordonMachine
summary: Uncordon a Fly Machine
description: >-
Restores a cordoned Fly Machine to the load balancer rotation, allowing
it to receive new traffic again. Use this endpoint after maintenance
or to complete a blue-green deployment cutover.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
responses:
'200':
description: Machine uncordoned successfully.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/machines/{machine_id}/metadata/{key}:
get:
operationId: getMachineMetadata
summary: Get a Machine metadata value
description: >-
Retrieves the value of a specific metadata key from a Fly Machine.
Machine metadata consists of arbitrary key-value string pairs that
can be used for internal routing, cluster membership, or application
configuration.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
- $ref: '#/components/parameters/metadataKey'
responses:
'200':
description: Metadata value.
content:
application/json:
schema:
type: string
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: setMachineMetadata
summary: Set a Machine metadata value
description: >-
Creates or updates a metadata key-value pair on a Fly Machine.
Metadata can be used for service discovery, internal routing with
fly-prefer-region headers, and cluster configuration.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
- $ref: '#/components/parameters/metadataKey'
requestBody:
required: true
content:
application/json:
schema:
type: string
description: The value to set for the metadata key.
responses:
'204':
description: Metadata set successfully.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteMachineMetadata
summary: Delete a Machine metadata value
description: >-
Removes a specific metadata key-value pair from a Fly Machine. Once
deleted, the key no longer appears in the Machine's metadata and
cannot be used for routing or configuration until it is re-added.
tags:
- Machines
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/machineId'
- $ref: '#/components/parameters/metadataKey'
responses:
'204':
description: Metadata deleted successfully.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/volumes:
get:
operationId: listVolumes
summary: List volumes in an app
description: >-
Returns a list of all Fly Volumes belonging to the specified app,
including their size, region, encryption status, attachment state,
and snapshot retention settings.
tags:
- Volumes
parameters:
- $ref: '#/components/parameters/appName'
responses:
'200':
description: A list of volumes.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Volume'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: createVolume
summary: Create a volume
description: >-
Creates a new Fly Volume in the specified app for use as persistent
storage attached to a Fly Machine. Volumes are region-specific and
are encrypted by default. Specify unique_zones_only to distribute
redundant volumes across separate physical hardware for higher
availability.
tags:
- Volumes
parameters:
- $ref: '#/components/parameters/appName'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateVolumeRequest'
responses:
'200':
description: Volume created successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/Volume'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/v1/apps/{app_name}/volumes/{volume_id}:
get:
operationId: getVolume
summary: Get a volume
description: >-
Retrieves the current state and configuration of a specific Fly Volume
by its ID, including size, region, filesystem type, encryption status,
and attachment information.
tags:
- Volumes
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/volumeId'
responses:
'200':
description: Volume details.
content:
application/json:
schema:
$ref: '#/components/schemas/Volume'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateVolume
summary: Update a volume
description: >-
Updates the configuration of an existing Fly Volume, such as adjusting
the snapshot retention period. Volume size can only be increased via
the extend endpoint; it cannot be reduced.
tags:
- Volumes
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/volumeId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
snapshot_retention:
type: integer
description: >-
Number of days to retain snapshots. Minimum 1, maximum 60.
minimum: 1
maximum: 60
responses:
'200':
description: Volume updated successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/Volume'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteVolume
summary: Delete a volume
description: >-
Permanently deletes a Fly Volume. The volume must not be currently
attached to a running Machine. Deleting a volume also removes all
snapshots associated with it. This operation is irreversible.
tags:
- Volumes
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/volumeId'
responses:
'200':
description: Volume deleted successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/Volume'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/volumes/{volume_id}/extend:
put:
operationId: extendVolume
summary: Extend a volume
description: >-
Increases the size of a Fly Volume without downtime or data loss.
Volume size can only be increased; shrinking a volume is not supported.
The Machine attached to the volume may need to be restarted for the
operating system to recognize the additional space.
tags:
- Volumes
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/volumeId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- size_gb
properties:
size_gb:
type: integer
description: >-
The new size of the volume in gigabytes. Must be larger
than the current size.
minimum: 1
responses:
'200':
description: Volume extended successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/Volume'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/apps/{app_name}/volumes/{volume_id}/snapshots:
get:
operationId: listVolumeSnapshots
summary: List volume snapshots
description: >-
Returns a list of all snapshots for a specific Fly Volume. Snapshots
are created automatically on a daily schedule and can also be created
on-demand. They are retained according to the volume's snapshot
retention setting.
tags:
- Volumes
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/volumeId'
responses:
'200':
description: A list of volume snapshots.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/VolumeSnapshot'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
operationId: createVolumeSnapshot
summary: Create a volume snapshot
description: >-
Creates an on-demand snapshot of a Fly Volume. Snapshots capture the
current state of the volume and can be used to restore data or create
new volumes from a known-good state.
tags:
- Volumes
parameters:
- $ref: '#/components/parameters/appName'
- $ref: '#/components/parameters/volumeId'
responses:
'200':
description: Snapshot creation initiated.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/tokens/oidc:
post:
operationId: getOidcToken
summary: Get an OIDC token
description: >-
Requests an OpenID Connect (OIDC) token for the calling Fly Machine.
The token can be used to authenticate to third-party services that
support OIDC workload identity, such as AWS, GCP, or Vault. The
optional aud field controls the audience claim embedded in the JWT.
tags:
- Tokens
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
aud:
type: string
description: >-
The audience claim for the OIDC token. Specifies the
recipient service that will accept this token, such as
https://fly.io/my-org-slug.
example: https://fly.io/my-org-slug
responses:
'200':
description: OIDC token as a raw JWT string.
content:
application/json:
schema:
type: string
description: A signed JWT OIDC token.
'401':
$ref: '#/components/responses/Unauthorized'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: >-
Fly.io API token obtained via the flyctl CLI using `flyctl auth token`.
Include it in all requests as: Authorization: Bearer <fly_api_token>.
parameters:
appName:
name: app_name
in: path
description: The name of the Fly App.
required: true
schema:
type: string
machineId:
name: machine_id
in: path
description: The unique identifier of the Fly Machine.
required: true
schema:
type: string
volumeId:
name: volume_id
in: path
description: The unique identifier of the Fly Volume.
required: true
schema:
type: string
metadataKey:
name: key
in: path
description: The metadata key to get, set, or delete.
required: true
schema:
type: string
orgSlug:
name: org_slug
in: query
description: The organization slug to filter apps by.
required: true
schema:
type: string
responses:
BadRequest:
description: Bad request due to invalid parameters or request body.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: Missing or invalid API token.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: The requested resource was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
schemas:
ErrorResponse:
type: object
description: A standard error response returned by the API on failure.
properties:
error:
type: string
description: Human-readable error message describing what went wrong.
status:
type: integer
description: HTTP status code.
App:
type: object
description: A Fly App, which is a logical grouping of related Fly Machines.
properties:
id:
type: string
description: Unique identifier for the app.
name:
type: string
description: The app name, used in routing and DNS.
status:
type: string
description: Current status of the app (e.g., running, suspended).
machine_count:
type: integer
description: Number of Machines currently in the app.
volume_count:
type: integer
description: Number of Volumes currently in the app.
network:
type: string
description: The private network name this app is attached to.
organization:
$ref: '#/components/schemas/Organization'
Organization:
type: object
description: A Fly.io organization that owns apps and resources.
properties:
name:
type: string
description: The organization name.
slug:
type: string
description: The organization's URL-safe identifier slug.
CreateAppRequest:
type: object
description: Request body for creating a new Fly App.
required:
- app_name
- org_slug
properties:
app_name:
type: string
description: The unique name for the new app.
org_slug:
type: string
description: The slug of the organization that will own this app.
enable_subdomains:
type: boolean
description: >-
When true, enables wildcard subdomain routing for this app.
network:
type: string
description: >-
Name of the private WireGuard network to attach this app to.
If omitted, the organization's default network is used.
Machine:
type: object
description: >-
A Fly Machine is a fast-booting virtual machine deployed on Fly.io's
global edge infrastructure.
properties:
id:
type: string
description: Stable unique identifier for this Machine.
name:
type: string
description: Human-readable name for this Machine.
state:
type: string
description: >-
Current lifecycle state of the Machine.
enum: [started, stopped, suspended, destroyed, replacing]
region:
type: string
description: The three-letter region code where this Machine is deployed.
example: iad
# --- truncated at 32 KB (43 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/fly-io/refs/heads/main/openapi/fly-io-machines-api-openapi.yml