---
title: "Operations & idempotency"
description: "Track long-running Metalhost mutations safely and retry requests without duplicating work."
url: "https://metalhost.net/docs/developers/guides/operations-idempotency"
---

# Operations & idempotency

Provisioning, deletion, resizing, cloning, and similar mutations can continue after the initial request returns. These APIs return an `operations/…` resource that records progress and the final outcome.

## Track an operation

Poll `OperationsService/GetOperation` until the state is `SUCCEEDED` or `FAILED`. The API does not expose customer cancellation because safe rollback depends on the operation.

```
metalhost vm create ... --wait

# Or save the returned operation name and wait later:
metalhost ops get operations/op_abc123
metalhost ops wait operations/op_abc123
```

Use `metalhost ops list` to inspect recent operations in the active project. On failure, read `errorMessage`. Successful operations can publish result identifiers in `metadata`, such as `virtual_machine_name`.

## Retry mutating HTTP requests

For operation-backed mutations, send a unique `Idempotency-Key` header and reuse that key only when retrying the same logical request. A retry can then resolve to the original operation instead of starting duplicate work.

```
curl -sS -X POST "$METALHOST_ENDPOINT/aes.compute.v1.ComputeService/CreateVirtualMachine" \
  -H "Authorization: Bearer $METALHOST_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: vm-create-$(uuidgen)" \
  -d @request.json
```

> **one key, one logical mutation**
>
> Do not reuse a key for a different method, resource, or payload. Idempotency records are retained for a limited window (currently 24 hours), so callers must still persist returned resource and operation names.

## Recommended client pattern

1. Generate and persist a key before sending the mutation.
2. Retry transient transport failures with the same key.
3. Persist the returned operation name.
4. Poll with backoff until `SUCCEEDED`, `FAILED`, or `CANCELLED`; do not resubmit merely because work is still running.
5. After success, fetch the resulting resource by its returned name.

## What's next

- [Concepts → Long-running operations](https://metalhost.net/docs/developers/concepts.md#operations)
- [CLI → Operations](https://metalhost.net/docs/developers/cli.md#ops)
- [Examples → Poll an operation](https://metalhost.net/docs/developers/examples.md#poll-operation)
