---
title: "Operation"
description: "An operation is a long-running PreForm API request that runs in the background in PreForm."
url: https://developer.formlabs.com/core-concepts/operation/
---

# Operation

An *operation* is a long-running PreForm API request that runs in the
background in PreForm. Importing, orienting, supporting, laying out, slicing,
and printing are the steps you wait on in the PreForm window, and they can take
seconds to minutes. PreForm accepts the request, returns an operation ID, and reports
progress until the work finishes.

![The Generating Supports progress bar partway through, after Auto-Generate All is clicked in the supports tool.](https://developer.formlabs.com/assets/images/screenshots/operation-generating-supports.png)

*In PreForm, a progress bar tracks support generation. Through the API, an operation reports its `progress`.*

## How an operation runs

A request with `async=true` starts an operation, and the client polls it until it
succeeds or fails:

```mermaid
sequenceDiagram
    participant C as Your code
    participant S as PreForm
    C->>S: POST /v1/scene/model/auto-support/?async=true
    S-->>C: 202 Accepted, operation_id
    loop Until status is SUCCEEDED or FAILED
        C->>S: GET /v1/operation/get/?operation_id=...
        S-->>C: status IN_PROGRESS, progress 0 to 1
    end
    S-->>C: status SUCCEEDED, result
```

An operation's `status` is `IN_PROGRESS` while it runs, then `SUCCEEDED` or `FAILED`.
Its `progress` value rises from 0 to 1. After it succeeds, `result` holds what the endpoint
returns when you call it without `async=true`.

## Wait for an operation

The SDK starts every long-running call as an operation and polls it for you, so a
blocking call returns when the work is done:

**SDK:**

```python
# The blocking call polls the operation until it succeeds or fails.
try:
    preform.auto_support_models(
        scene_id=scene.scene_id,
        timeout=300,
        # Called each time the progress, from 0 to 1, increases.
        on_progress=lambda p: print(f"Supports {p:.0%}"),
    )
except TimeoutError:
    # The PreForm API can't cancel an operation, so it keeps running.
    print("Still running in PreForm after 300 seconds")
```

**curl:**

**macOS:**

```bash
curl -X POST "http://localhost:44388/v1/scene/model/auto-support/?async=true" \
    -H "Content-Type: application/json" \
    -d "{\"scene_id\": \"$SCENE_ID\"}"
curl "http://localhost:44388/v1/operation/get/?operation_id=$OPERATION_ID"
```

**Windows:**

```powershell
@{ scene_id = $env:SCENE_ID } |
    ConvertTo-Json |
    curl.exe -X POST "http://localhost:44388/v1/scene/model/auto-support/?async=true" `
        -H "Content-Type: application/json" `
        -d "@-"
curl.exe "http://localhost:44388/v1/operation/get/?operation_id=$env:OPERATION_ID"
```

The `on_progress` callback receives the progress each time it increases. A call that
runs past `timeout` raises `TimeoutError`, and the operation keeps running in
PreForm, because the PreForm API has no endpoint that cancels an operation.

**Caution:** Don't retry a timed-out call on the same scene while the first operation
still runs. The PreForm API reference states that parallel requests that change one
scene overwrite each other, and the last write wins silently.

## What an operation doesn't cover

An operation lives only as long as the PreForm process, and a restarted PreForm
holds no operations. A print job that PreForm has uploaded is no longer an
operation: the printer and its queue track it from then on. For more information, see
[Queue](https://developer.formlabs.com/core-concepts/queue.md).

## What's next

- [Device](https://developer.formlabs.com/core-concepts/device.md)
