Skip to content

PATCH /api/v1/hosts/machines/{id}/offer

Operation: editOffer.

Edit the listing by publishing the next offer version (host owner)

The host console’s listing editor. Despite the verb this is APPEND-ONLY: the next version is inserted and no existing row is ever rewritten, so a live job keeps the rate its quote snapshotted — the quote remains the only price authority. expected_version is compare-and-swapped against the CURRENT offer version (not the machine version the POST form uses); a race answers 409 with error.code = VERSION_CONFLICT and a sibling current block so the editor can show what changed instead of overwriting it. listing_expires_at has no column of its own and is FOLDED onto available_until (the earlier of the two wins — available_until already means “bookable until”, which is what the catalog filters on); the response echoes the stored value. min_duration_s and max_duration_s are accepted but NOT stored, because no per-offer duration bound exists in the schema and nothing at quote time would enforce one; they are named back to the caller in ignored_fields rather than silently dropped. A publish that would retract availability a live job is already holding is refused 409 CONFLICT.

PATCH https://amplerun-api.spiry.org/api/v1/hosts/machines/{id}/offer

Use the credential and scope required by this operation. For programmatic renter/host calls: Authorization: Bearer $AMPLERUN_API_KEY. A host-agent signature or other specialized proof is required where the description specifies it.

NameLocationPresenceTypeDescription
idpathRequiredUUID
Idempotency-KeyheaderRequiredUUIDUUID scoped to authenticated principal, route and canonical request hash.

Required body.

FieldTypePresenceDescription
expected_versionDecimalStringRequired
rate_micro_per_hourMicroAmountRequired
included_disk_gibintegerRequired
included_egress_gibintegerRequired
available_fromRfc3339UtcRequired
available_untilRfc3339UtcRequired
listing_expires_atRfc3339UtcOptional
min_duration_sintegerOptionalAccepted, never stored; reported in ignored_fields.
max_duration_sintegerOptionalAccepted, never stored; reported in ignored_fields.
availability_classAvailabilityClassOptionalD-22. Omitted keeps the current version’s class. interruptible needs preemption_notice_s; an idle or co-listed host can rent only interruptible offers. 409 until the D-22 migration is released.
preemption_notice_sintegerOptionalD-22. Required for interruptible, refused for dedicated; omitted keeps the current value.
{
"type": "object",
"additionalProperties": false,
"required": [
"expected_version",
"rate_micro_per_hour",
"included_disk_gib",
"included_egress_gib",
"available_from",
"available_until"
],
"properties": {
"expected_version": {
"$ref": "#/components/schemas/DecimalString"
},
"rate_micro_per_hour": {
"$ref": "#/components/schemas/MicroAmount"
},
"included_disk_gib": {
"type": "integer",
"minimum": 0
},
"included_egress_gib": {
"type": "integer",
"minimum": 0
},
"available_from": {
"$ref": "#/components/schemas/Rfc3339Utc"
},
"available_until": {
"$ref": "#/components/schemas/Rfc3339Utc"
},
"listing_expires_at": {
"$ref": "#/components/schemas/Rfc3339Utc"
},
"min_duration_s": {
"type": "integer",
"minimum": 0,
"description": "Accepted, never stored; reported in ignored_fields."
},
"max_duration_s": {
"type": "integer",
"minimum": 0,
"description": "Accepted, never stored; reported in ignored_fields."
},
"availability_class": {
"$ref": "#/components/schemas/AvailabilityClass",
"description": "D-22. Omitted keeps the current version's class. interruptible needs preemption_notice_s; an idle or co-listed host can rent only interruptible offers. 409 until the D-22 migration is released."
},
"preemption_notice_s": {
"type": "integer",
"minimum": 0,
"maximum": 3600,
"description": "D-22. Required for interruptible, refused for dedicated; omitted keeps the current value."
}
}
}

Next offer version published.

application/json

FieldTypePresenceDescription
offer_idUUIDRequired
offer_versionDecimalStringRequired
state“listed” / “unlisted” / “draining”Required
rate_micro_per_hourMicroAmountRequired
included_disk_gibintegerRequired
included_egress_gibintegerRequired
available_fromRfc3339UtcRequired
available_untilRfc3339UtcRequired
availability_classAvailabilityClassOptional
preemption_notice_sinteger or nullOptional
ignored_fieldsarray of stringRequiredRequest fields accepted by the schema but deliberately not stored.
{
"type": "object",
"additionalProperties": false,
"required": [
"offer_id",
"offer_version",
"state",
"rate_micro_per_hour",
"included_disk_gib",
"included_egress_gib",
"available_from",
"available_until",
"ignored_fields"
],
"properties": {
"offer_id": {
"$ref": "#/components/schemas/UUID"
},
"offer_version": {
"$ref": "#/components/schemas/DecimalString"
},
"state": {
"type": "string",
"enum": [
"listed",
"unlisted",
"draining"
]
},
"rate_micro_per_hour": {
"$ref": "#/components/schemas/MicroAmount"
},
"included_disk_gib": {
"type": "integer",
"minimum": 0
},
"included_egress_gib": {
"type": "integer",
"minimum": 0
},
"available_from": {
"$ref": "#/components/schemas/Rfc3339Utc"
},
"available_until": {
"$ref": "#/components/schemas/Rfc3339Utc"
},
"availability_class": {
"$ref": "#/components/schemas/AvailabilityClass"
},
"preemption_notice_s": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 3600
},
{
"type": "null"
}
]
},
"ignored_fields": {
"type": "array",
"description": "Request fields accepted by the schema but deliberately not stored.",
"items": {
"type": "string"
}
}
}
}

Offer version race (VERSION_CONFLICT, with current) or a live job whose availability the change would retract (CONFLICT).

application/json

FieldTypePresenceDescription
errorobjectRequired
currentobjectOptionalPresent only for VERSION_CONFLICT — the listing as it now stands.
{
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message",
"retryable",
"request_id"
],
"properties": {
"code": {
"type": "string",
"enum": [
"VERSION_CONFLICT",
"CONFLICT",
"IDEMPOTENCY_CONFLICT"
]
},
"message": {
"type": "string"
},
"retryable": {
"type": "boolean"
},
"request_id": {
"$ref": "#/components/schemas/UUID"
}
}
},
"current": {
"type": "object",
"description": "Present only for VERSION_CONFLICT — the listing as it now stands.",
"additionalProperties": false,
"required": [
"offer_version",
"rate_micro_per_hour",
"available_until"
],
"properties": {
"offer_version": {
"$ref": "#/components/schemas/DecimalString"
},
"rate_micro_per_hour": {
"$ref": "#/components/schemas/MicroAmount"
},
"available_until": {
"$ref": "#/components/schemas/Rfc3339Utc"
}
}
}
}
}

Error envelope. 401 unauthenticated, 403/404 forbidden, 409 conflict, 422 invalid input, 429 rate limited (code UNAVAILABLE, retryable:true, no Retry-After header), 503 unavailable money/provider state with retryable:true.

application/json

FieldTypePresenceDescription
errorobjectRequired
{
"$ref": "#/components/schemas/ErrorEnvelope"
}

Replace path/query placeholders and provide the required JSON body, headers and credential from the sections above. This is a request outline, not a command that chooses an amount or starts a rental for you.

Terminal window
curl --request PATCH 'https://amplerun-api.spiry.org/api/v1/hosts/machines/{id}/offer' \
--header "Authorization: Bearer $AMPLERUN_API_KEY"

Schema definitions · Download OpenAPI · Authentication · Errors and recovery

Official AmpleRun documentation · Contract v3 · Generated from the API contract · Revision 52fe29de · Open AmpleRun · View Markdown · For agents