> ## Documentation Index
> Fetch the complete documentation index at: https://www.octoparse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Crea build

> Congela la bozza corrente in uno snapshot immutabile per run di debug e publishing.

**`POST`** `https://api-datahub.octoparse.com/v1/data-apps/{app_id}/builds`

Autenticazione: API key obbligatoria (`Authorization: Bearer <API Key>`). Solo autore dell’app; gli altri ricevono `404`.

Congela il workspace corrente in uno snapshot immutabile: l'oggetto a cui fanno riferimento i run di debug e la pubblicazione.

Condizioni preliminari: uno spazio di lavoro deve esistere e il suo contenuto corrente deve essere valido (altrimenti `422` con `issues`); il corpo può includere `expected_revision` (`409` se la bozza è cambiata tra salvataggio e blocco). Se esiste⟧ già un'istantanea pronta con lo stesso ⟦4, viene riutilizzata e non viene creata alcuna riga duplicata. le build di tipo api diventano immediatamente pronte; il tipo di codice restituisce `202` e accoda una build di immagine — l'invio di nuovo mentre uno è già in corso per la stessa app restituisce `409`. Le app obsolete possono ancora essere create; solo le nuove versioni vengono rifiutate.

## Richiesta

### Parametri di percorso

<ParamField path="app_id" type="string" required>
  Riferimento app.
</ParamField>

### Body della richiesta

<ParamField body="expected_revision" type="integer">
  Expected current draft revision. Mismatch restituisce `409`.
</ParamField>

### Esempio di richiesta

```bash theme={null}
curl -X POST \
  -H "Authorization: Bearer $OCTOPARSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expected_revision": 3}' \
  "https://api-datahub.octoparse.com/v1/data-apps/carol/reviews-query/builds"
```

## Risposta

### 200 successo

```json theme={null}
{
  "data": {
    "build_id": "string",
    "build_status": "string",
    "content_hash": "string",
    "source_revision": 0,
    "reused": false,
    "created_at": "string"
  }
}
```

Il payload è wrappato in `data`. Campi:

<ResponseField name="build_id" type="string" required>
  ID della build.
</ResponseField>

<ResponseField name="build_status" type="string" required>
  `ready`, `building` (code-type) o `failed`.
</ResponseField>

<ResponseField name="content_hash" type="string" required>
  Hash del contenuto.
</ResponseField>

<ResponseField name="source_revision" type="integer" required>
  Revisione del draft al momento del congelamento.
</ResponseField>

<ResponseField name="reused" type="boolean">
  Se an existing same-content snapshot was reused.
</ResponseField>

<ResponseField name="created_at" type="string">
  Ora di creazione.
</ResponseField>

### Errori

| HTTP | `code`                | `category`      | Descrizione                                                                                 |
| ---- | --------------------- | --------------- | ------------------------------------------------------------------------------------------- |
| 401  | `unauthorized`        | `forbidden`     | API key mancante o non valida.                                                              |
| 404  | `workspace-not-found` | `not_found`     | Questa app non ha una bozza in corso. È uno stato normale del main path, non un fault.      |
| 422  | `build-failed`        | `invalid_input` | Il contenuto del workspace non ha superato la validazione; `issues[]` elenca i problemi.    |
| 409  | `revision-conflict`   | `invalid_input` | `expected_revision` non corrisponde alla revisione attuale del draft: modifica concorrente. |

Le risposte di errore usano `{"error": {code, category, message, retryable}}`. Vedi <a href="/docs/it/datahub/api/reference/introduction#errors">Errori</a>.

## Librerie client

Gli SDK Python e JavaScript non wrappano ancora questo endpoint. Chiama REST direttamente.
