# API REST: deploy dalla CI e automazione dei server

> Riferimento dell'API REST di Vimonto Deploy: token API e ambiti, ogni endpoint con esempi, task, errori, limiti di frequenza e un deploy con GitHub Actions.

L'API di Vimonto Deploy permette a script e pipeline CI di lavorare con le tue organizzazioni tramite HTTPS e JSON: elencare server e siti, avviare un deploy e seguirlo, creare e rimuovere database, eseguire backup e ricette. Ogni richiesta è autenticata con un token API personale che crei nel tuo account.

Un token agisce come te. Può fare solo ciò che il tuo [ruolo](https://ops.vimonto.com/docs/it/organization/members-and-roles) consente, solo sui server a cui hai accesso e solo entro gli ambiti che gli hai assegnato.

![La pagina dei token API con un elenco di token e i loro ambiti](https://ops.vimonto.com/docs-media/it/account-api-tokens.webp?v=161e760d "Token API nel tuo account")

## Creare un token API

1. Apri il menu account in alto a destra e scegli **Impostazioni account** → **Token API**.
2. Fai clic su **Nuovo token**.
3. Inserisci un **Nome** che indichi dove viene usato, per esempio "GitHub Actions".
4. In **Ambiti**, seleziona cosa può fare il token (vedi sotto).
5. In **Scade**, scegli **Tra 30 giorni**, **Tra 90 giorni** (il valore predefinito), **Tra 365 giorni** o **Mai**.
6. Fai clic su **Crea token**.

Il token viene mostrato una sola volta, in **Il tuo nuovo token**. Fai clic su **Copia** e conservalo in un posto sicuro, come i secret della tua CI; Vimonto Deploy ne conserva solo un hash e non può mostrarlo di nuovo. Un token è fatto così: `12|` seguito da una lunga stringa di lettere e cifre.

L'elenco mostra per ogni token il nome, quando è stato usato l'ultima volta, quando scade e i suoi ambiti. Fai clic su **Revoca** per eliminare un token: script e pipeline che lo usano smettono subito di funzionare. Eliminando il tuo account revochi tutti i tuoi token.

### Ambiti

| Ambito | Valore | Consente |
|---|---|---|
| **Lettura** | `read` | Vedere server, siti, deploy, database, backup, ricette e task. |
| **Deploy** | `deploy` | Avviare deploy e seguirli: trovare un sito per dominio o ID, elencare e vedere i deploy e vedere i task. Pensato per le pipeline CI. |
| **Scrittura** | `write` | Tutto ciò che consente **Lettura**, più avviare deploy, creare e rimuovere database ed eseguire backup e ricette. |

Un token con solo **Deploy** può cercare il sito di cui fa il deploy (vedi [trovare un sito](#trovare-un-sito)), ma non può elencare server o siti: dai a una pipeline CI solo questo ambito e usa **Lettura** o **Scrittura** per gli script che hanno bisogno di più.

L'ambito è il primo controllo. Il tuo ruolo è il secondo: avviare un deploy, modificare database ed eseguire backup o ricette richiedono il ruolo di proprietario, amministratore, manager o sviluppatore. Il token di un osservatore può leggere, ma ogni modifica viene rifiutata con `403`.

## URL di base e autenticazione

Tutti gli endpoint si trovano sotto `/api/v1` all'indirizzo dove usi Vimonto Deploy. Negli esempi qui sotto è `https://deploy.example.com/api/v1`; sostituisci `deploy.example.com` con il tuo indirizzo.

Invia il token come bearer token nell'header `Authorization` e chiedi JSON:

```bash
curl https://deploy.example.com/api/v1/user \
  -H "Authorization: Bearer $VIMONTO_TOKEN" \
  -H "Accept: application/json"
```

Solo i token aprono l'API: aver effettuato l'accesso all'app nel browser non basta. I corpi delle richieste sono JSON (`Content-Type: application/json`). Le date sono in ISO 8601 con fuso orario. I messaggi nelle risposte, come gli errori, sono nella lingua impostata nel tuo account; se non ne hai scelta una, nella lingua dell'header `Accept-Language` della richiesta (inglese, olandese, tedesco, francese o italiano), altrimenti in inglese.

### Organizzazioni, server e siti nell'URL

Gli endpoint di un'organizzazione iniziano con `/orgs/{organization}`, dove `{organization}` è lo slug dell'organizzazione: la prima parte del suo indirizzo nell'app (`https://deploy.example.com/acme/…` ha lo slug `acme`). `GET /user` elenca gli slug che il tuo token può raggiungere.

Server, siti e tutto ciò che sta sotto sono indicati con il loro ID numerico, lo stesso numero che compare nell'indirizzo dell'app: `/acme/servers/12/sites/34` nell'app è `/orgs/acme/servers/12/sites/34` nell'API. Un elemento figlio deve appartenere al suo genitore: il sito 34 sul server 12 funziona solo se il sito si trova su quel server, altrimenti l'API risponde `404`.

Un'organizzazione di cui non sei membro, e un server a cui i tuoi [team](https://ops.vimonto.com/docs/it/organization/teams) non ti danno accesso, rispondono `404`, non `403`.

## Endpoint

| Metodo | Percorso | Ambiti |
|---|---|---|
| `GET` | `/user` | qualsiasi |
| `GET` | `/orgs/{organization}/servers` | read, write |
| `GET` | `/orgs/{organization}/servers/{server}` | read, write |
| `GET` | `/orgs/{organization}/servers/{server}/sites` | read, write |
| `GET` | `/orgs/{organization}/servers/{server}/sites/{site}` | read, write |
| `GET` | `/orgs/{organization}/sites` | read, deploy, write |
| `GET` | `/orgs/{organization}/servers/{server}/sites/{site}/deployments` | read, deploy, write |
| `GET` | `/orgs/{organization}/servers/{server}/sites/{site}/deployments/{deployment}` | read, deploy, write |
| `POST` | `/orgs/{organization}/servers/{server}/sites/{site}/deployments` | deploy, write |
| `GET` | `/orgs/{organization}/servers/{server}/databases` | read, write |
| `POST` | `/orgs/{organization}/servers/{server}/databases` | write |
| `DELETE` | `/orgs/{organization}/servers/{server}/databases/{database}` | write |
| `GET` | `/orgs/{organization}/servers/{server}/backups` | read, write |
| `POST` | `/orgs/{organization}/servers/{server}/backups/{backup}/run` | write |
| `GET` | `/orgs/{organization}/recipes` | read, write |
| `POST` | `/orgs/{organization}/recipes/{recipe}/run` | write |
| `GET` | `/orgs/{organization}/tasks/{task}` | read, deploy, write |

Un token ha bisogno di uno degli ambiti indicati. I percorsi qui sotto omettono il prefisso `https://deploy.example.com/api/v1`.

### Ottenere l'utente del token

`GET /user` restituisce a chi appartiene il token, il nome e gli ambiti del token e le organizzazioni che può raggiungere, con il tuo ruolo in ciascuna. Ogni ambito può chiamarlo, quindi è un buon primo test per un token.

```bash
curl https://deploy.example.com/api/v1/user \
  -H "Authorization: Bearer $VIMONTO_TOKEN" -H "Accept: application/json"
```

```json
{
  "data": {
    "id": 7,
    "name": "Sam de Vries",
    "email": "sam@example.com",
    "token": {
      "name": "GitHub Actions",
      "scopes": ["deploy"]
    },
    "organizations": [
      { "slug": "acme", "name": "Acme", "role": "developer" }
    ]
  }
}
```

### Elencare i server

`GET /orgs/{organization}/servers` restituisce i server dell'organizzazione a cui hai accesso, in ordine di nome. `GET /orgs/{organization}/servers/{server}` restituisce un solo server.

```bash
curl https://deploy.example.com/api/v1/orgs/acme/servers \
  -H "Authorization: Bearer $VIMONTO_TOKEN" -H "Accept: application/json"
```

```json
{
  "data": [
    {
      "id": 12,
      "name": "web-1",
      "type": "app",
      "status": "active",
      "provider": "hetzner",
      "region": "fsn1",
      "size": "cx32",
      "ip_address": "203.0.113.10",
      "private_ip_address": "10.0.0.2",
      "ssh_port": 22,
      "user": "vimonto",
      "php_version": "8.4",
      "database": "mysql-8.4",
      "ubuntu_version": "24.04",
      "timezone": "UTC",
      "tags": ["production"],
      "created_at": "2026-09-01T09:30:00+00:00"
    }
  ]
}
```

| Campo | Valori |
|---|---|
| `type` | `app`, `web`, `worker`, `database`, `cache`, `meilisearch`, `loadbalancer` |
| `status` | `creating`, `waiting`, `provisioning`, `active`, `failed`, `disconnected`, `deleting` |
| `provider` | Il [provider cloud](https://ops.vimonto.com/docs/it/connections/server-providers), oppure `custom` per un [VPS personalizzato](https://ops.vimonto.com/docs/it/servers/custom-vps). |
| `database` | `mysql-8.4`, `mysql-8.0`, `mariadb-11.4`, `mariadb-10.11`, `postgres-18`, `postgres-17`, `postgres-16`, oppure `null` |

Segreti come password e chiavi non fanno mai parte di una risposta.

### Elencare i siti

`GET /orgs/{organization}/servers/{server}/sites` restituisce i siti del server, in ordine di dominio. `GET /orgs/{organization}/servers/{server}/sites/{site}` restituisce un solo sito.

```json
{
  "data": {
    "id": 34,
    "server_id": 12,
    "domain": "shop.example.com",
    "aliases": ["www.shop.example.com"],
    "preview_domain": "kalme-rivier-4821.on-deploy.link",
    "framework": "laravel",
    "status": "installed",
    "php_version": "8.4",
    "repository": "acme/shop",
    "branch": "main",
    "quick_deploy": true,
    "zero_downtime": true,
    "isolated": false,
    "current_release": "20261007143012",
    "deployed_at": "2026-10-07T14:31:40+00:00",
    "created_at": "2026-09-01T10:02:11+00:00"
  }
}
```

`framework` è uno tra `laravel`, `symfony`, `statamic`, `wordpress`, `phpmyadmin`, `php`, `nextjs`, `nuxt`, `html`, `other` e `loadbalancer`. `status` è `installed` quando il sito è pronto; mentre cambia è `installing`, `updating` o `removing`, e `failed` quando qualcosa è andato storto. `quick_deploy` è il deploy a ogni push; `isolated` indica se il sito gira con un proprio utente Linux. Il file di ambiente del sito e l'URL di deploy non vengono mai restituiti.

### Trovare un sito

`GET /orgs/{organization}/sites` restituisce i siti su tutti i server a cui hai accesso, in ordine di dominio, ciascuno con il suo `server` (ID e nome). Gli altri campi sono gli stessi visti sopra. Restringi l'elenco con i parametri della query:

| Parametro | Cerca per |
|---|---|
| `domain` | Il dominio del sito, senza distinguere maiuscole e minuscole. |
| `id` | L'ID del sito. |
| `server` | L'ID o il nome del server. |

```bash
curl "https://deploy.example.com/api/v1/orgs/acme/sites?domain=shop.example.com" \
  -H "Authorization: Bearer $VIMONTO_TOKEN" -H "Accept: application/json"
```

```json
{
  "data": [
    {
      "id": 34,
      "server_id": 12,
      "server": { "id": 12, "name": "web-1" },
      "domain": "shop.example.com",
      "status": "installed",
      "branch": "main"
    }
  ]
}
```

Anche un token con il solo ambito **Deploy** può chiamarlo, per trovare il sito di cui fa il deploy, ma deve indicare `domain` o `id`; senza, la risposta è `422`. Se nulla corrisponde, `data` è un elenco vuoto.

### Elencare i deploy

`GET /orgs/{organization}/servers/{server}/sites/{site}/deployments` restituisce i deploy del sito, dal più recente, 25 per pagina (vedi [paginazione](#paginazione)). `GET …/deployments/{deployment}` ne restituisce uno.

```json
{
  "data": {
    "id": 581,
    "site_id": 34,
    "status": "succeeded",
    "trigger": "api",
    "branch": "main",
    "commit": {
      "hash": "9f2c4e1a7b3d5f60812a9c4e7d1b3a5c7e9f1a2b",
      "author": "Sam de Vries",
      "message": "Add checkout page"
    },
    "release": "20261007143012",
    "task_id": 9120,
    "started_at": "2026-10-07T14:30:12+00:00",
    "finished_at": "2026-10-07T14:31:40+00:00",
    "created_at": "2026-10-07T14:30:11+00:00"
  }
}
```

| Campo | Valori |
|---|---|
| `status` | `queued`, `running`, `succeeded`, `failed`, `cancelled` |
| `trigger` | `manual`, `push`, `url` (l'URL di deploy), `rollback`, `api` |
| `commit` | `null` finché il codice non è stato scaricato. |
| `release` | La directory della release, oppure `live` per un sito senza deploy zero-downtime; `null` finché il deploy non è iniziato. |

### Avviare un deploy

`POST /orgs/{organization}/servers/{server}/sites/{site}/deployments` fa il deploy del branch del sito, esattamente come **Fai il deploy** nell'app. Non ha corpo. Risponde `202 Accepted` con il nuovo deploy; seguilo tramite il suo `task_id`.

```bash
curl -X POST https://deploy.example.com/api/v1/orgs/acme/servers/12/sites/34/deployments \
  -H "Authorization: Bearer $VIMONTO_TOKEN" -H "Accept: application/json"
```

```json
{
  "data": {
    "id": 582,
    "site_id": 34,
    "status": "queued",
    "trigger": "api",
    "branch": "main",
    "commit": null,
    "release": null,
    "task_id": 9121,
    "started_at": null,
    "finished_at": null,
    "created_at": "2026-10-07T15:02:45+00:00"
  }
}
```

- `409` quando è già in corso un deploy del sito; il `task_id` nella risposta è il task in corso.
- `422` quando il sito non è ancora pronto per il deploy o non ha un repository.

Vedi [deploy](https://ops.vimonto.com/docs/it/sites/deployments) per cosa fa un deploy.

### Elencare e creare database

`GET /orgs/{organization}/servers/{server}/databases` restituisce i database del server, in ordine di nome.

```json
{
  "data": [
    { "id": 3, "server_id": 12, "name": "shop", "status": "installed", "created_at": "2026-09-01T10:05:00+00:00" }
  ]
}
```

`POST /orgs/{organization}/servers/{server}/databases` crea un database sul server. Il corpo ha un solo campo:

| Campo | Regole |
|---|---|
| `name` | Obbligatorio. Da 1 a 63 lettere, cifre e trattini bassi, unico sul server. |

```bash
curl -X POST https://deploy.example.com/api/v1/orgs/acme/servers/12/databases \
  -H "Authorization: Bearer $VIMONTO_TOKEN" -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name": "shop_staging"}'
```

```json
{
  "data": { "id": 4, "server_id": 12, "name": "shop_staging", "status": "installing", "created_at": "2026-10-07T15:10:00+00:00", "task_id": 9122 }
}
```

La risposta è `202`: il database viene creato da un task sul server. Il suo `status` è `installing`, poi `installed`, oppure `failed` se il task non riesce. Il server deve essere attivo e avere un database installato, altrimenti la risposta è `422`.

### Eliminare un database

`DELETE /orgs/{organization}/servers/{server}/databases/{database}` elimina il database sul server. Risponde `202` con il database, ora `removing`, e il task che lo rimuove in `task_id`, dentro `data` come ogni endpoint che avvia un task:

```json
{
  "data": { "id": 4, "server_id": 12, "name": "shop_staging", "status": "removing", "created_at": "2026-10-07T15:10:00+00:00", "task_id": 9123 }
}
```

> [!WARNING]
> Questo elimina il database e tutti i suoi dati sul server. Non si può annullare.

Vedi [database](https://ops.vimonto.com/docs/it/servers/databases).

### Elencare i backup ed eseguirne uno

`GET /orgs/{organization}/servers/{server}/backups` restituisce le configurazioni di backup del server, in ordine di nome, ciascuna con i suoi 20 backup più recenti. `size` è in byte.

```json
{
  "data": [
    {
      "id": 2,
      "name": "Nightly",
      "databases": ["shop"],
      "frequency": "nightly",
      "schedule": "0 0 * * *",
      "retention": 7,
      "storage": "Backups bucket",
      "backups": [
        {
          "id": 140,
          "status": "succeeded",
          "size": 48213504,
          "databases": ["shop"],
          "task_id": 9050,
          "created_at": "2026-10-07T00:00:02+00:00",
          "finished_at": "2026-10-07T00:01:15+00:00"
        }
      ]
    }
  ]
}
```

`frequency` è `minute`, `hourly`, `nightly`, `weekly`, `monthly`, `reboot` o `custom`; `schedule` è l'espressione cron. Lo `status` di un backup è `running`, `succeeded` o `failed`.

`POST /orgs/{organization}/servers/{server}/backups/{backup}/run`, con l'ID di una configurazione di backup, avvia subito un backup. Non ha corpo e risponde `202`:

```json
{ "data": { "backup_id": 141, "task_id": 9124 } }
```

`409` quando è già in corso un backup di quella configurazione. Vedi [backup](https://ops.vimonto.com/docs/it/servers/backups).

### Elencare le ricette ed eseguirne una

`GET /orgs/{organization}/recipes` restituisce le ricette dell'organizzazione, in ordine di nome. `run_as` è `root` o `server_user`.

```json
{
  "data": [
    { "id": 5, "name": "Install htop", "run_as": "root", "script": "apt-get install -y htop", "updated_at": "2026-09-20T08:12:00+00:00" }
  ]
}
```

`POST /orgs/{organization}/recipes/{recipe}/run` esegue una ricetta su uno o più server.

| Campo | Regole |
|---|---|
| `servers` | Obbligatorio. Un elenco di ID di server, almeno uno. |
| `notify` | Facoltativo, `true` o `false` (predefinito). Con `true` ricevi un report via email quando tutti i server hanno finito. |

```bash
curl -X POST https://deploy.example.com/api/v1/orgs/acme/recipes/5/run \
  -H "Authorization: Bearer $VIMONTO_TOKEN" -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"servers": [12, 13], "notify": false}'
```

```json
{
  "data": {
    "run_id": 77,
    "servers": [
      { "server_id": 12, "task_id": 9125 },
      { "server_id": 13, "task_id": 9126 }
    ]
  }
}
```

Ogni server che indichi deve esistere, esserti accessibile ed essere attivo. Altrimenti la ricetta non viene eseguita da nessuna parte e la risposta è `422`: `errors.servers` elenca gli ID dei server che non esistono o a cui non hai accesso, oppure i nomi dei server non attivi. La risposta elenca ogni server con il proprio task. Vedi [ricette](https://ops.vimonto.com/docs/it/more/recipes).

### Seguire un task

Il lavoro lungo (un deploy, un database, un backup, una ricetta su un server) gira come task in background, lo stesso che vedi in [attività](https://ops.vimonto.com/docs/it/organization/activity). `GET /orgs/{organization}/tasks/{task}` ne restituisce lo stato e l'output:

```json
{
  "data": {
    "id": 9121,
    "type": "site.deploy",
    "name": "Deploying to shop.example.com",
    "status": "running",
    "step": "Run deploy script",
    "progress": 30,
    "error": null,
    "server_id": 12,
    "output": "Cloning into 'releases/20261007150246'...\n",
    "started_at": "2026-10-07T15:02:46+00:00",
    "finished_at": null,
    "created_at": "2026-10-07T15:02:45+00:00"
  }
}
```

`status` è `queued`, `running`, `succeeded`, `failed` o `cancelled`; gli ultimi tre sono definitivi. `progress` va da 0 a 100. Quando un task non riesce, `error` spiega perché. Interroga l'endpoint ogni pochi secondi finché lo stato non è definitivo.

## Paginazione

Solo l'elenco dei deploy è paginato, con 25 deploy per pagina, dal più recente. Chiedi un'altra pagina con `?page=2`. La risposta contiene `links` e `meta` accanto a `data`:

```json
{
  "data": [ … ],
  "links": {
    "first": "https://deploy.example.com/api/v1/orgs/acme/servers/12/sites/34/deployments?page=1",
    "last": "https://deploy.example.com/api/v1/orgs/acme/servers/12/sites/34/deployments?page=4",
    "prev": null,
    "next": "https://deploy.example.com/api/v1/orgs/acme/servers/12/sites/34/deployments?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 4,
    "path": "https://deploy.example.com/api/v1/orgs/acme/servers/12/sites/34/deployments",
    "per_page": 25,
    "to": 25,
    "total": 92
  }
}
```

`meta` contiene anche un elenco `links` per i pulsanti delle pagine. Segui `links.next` finché non è `null`. Tutti gli altri elenchi restituiscono tutto in una sola risposta.

## Errori

Gli errori sono JSON con un `message`:

```json
{ "message": "shop.example.com is not ready to deploy yet." }
```

| Stato | Significato |
|---|---|
| `401` | Nessun token, un token sbagliato o revocato, oppure scaduto: `{"message": "Unauthenticated."}` |
| `403` | Al token manca l'ambito (`"Invalid ability provided."`), oppure il tuo ruolo non consente la modifica (`"Your role does not allow this."`). |
| `404` | L'organizzazione, il server, il sito o un altro elemento non esiste, oppure non hai accesso. Non fare affidamento sul `message`. |
| `409` | Lo stesso lavoro è già in corso. La risposta contiene il `task_id` del task in corso. |
| `422` | La richiesta non si può eseguire: campi non validi, oppure un motivo come un server non ancora pronto. |
| `429` | Troppe richieste; vedi [limiti di frequenza](#limiti-di-frequenza). |

Un `409` è fatto così:

```json
{ "message": "Deploying to shop.example.com is already running.", "task_id": 9121 }
```

Un `422` per campi non validi li elenca in `errors`:

```json
{
  "message": "The name field format is invalid.",
  "errors": {
    "name": ["The name field format is invalid."]
  }
}
```

## Limiti di frequenza

Ogni token può fare 120 richieste al minuto. Ogni risposta ha gli header `X-RateLimit-Limit` e `X-RateLimit-Remaining`. Oltre il limite, l'API risponde `429` con un header `Retry-After`: il numero di secondi da attendere.

Quando interroghi un task, una volta ogni pochi secondi è più che sufficiente.

## Deploy da GitHub Actions

Questo workflow fa il deploy dopo che i test sono passati e fallisce quando il deploy non riesce. Crea un token con solo l'ambito **Deploy** e aggiungilo ai secret del repository come `VIMONTO_TOKEN` (**Settings** → **Secrets and variables** → **Actions** su GitHub). Inserisci il tuo indirizzo, lo slug dell'organizzazione, l'ID del server e l'ID del sito.

```yaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    # needs: tests   # deploy solo dopo che il job dei test è passato
    steps:
      - name: Deploy to production
        env:
          VIMONTO_TOKEN: ${{ secrets.VIMONTO_TOKEN }}
          API: https://deploy.example.com/api/v1/orgs/acme
          SERVER: 12
          SITE: 34
        run: |
          set -euo pipefail
          auth=(-H "Authorization: Bearer $VIMONTO_TOKEN" -H "Accept: application/json")

          # Avvia il deploy; curl fallisce con 4xx/5xx, per esempio 409 se ne è già in corso uno.
          task=$(curl -sS --fail-with-body -X POST "${auth[@]}" \
            "$API/servers/$SERVER/sites/$SITE/deployments" | jq -r '.data.task_id')
          echo "Deploy started, task $task"

          # Segui il task finché non è terminato.
          while true; do
            sleep 5
            response=$(curl -sS --fail-with-body "${auth[@]}" "$API/tasks/$task")
            status=$(echo "$response" | jq -r '.data.status')
            echo "Status: $status ($(echo "$response" | jq -r '.data.step // ""'))"
            case "$status" in
              succeeded) exit 0 ;;
              failed|cancelled)
                echo "$response" | jq -r '.data.error // "", .data.output'
                exit 1 ;;
            esac
          done
```

Disattiva **Deploy a ogni push** per il sito quando è la CI a fare il deploy. Altrimenti un push avvia già da solo un deploy, e la richiesta della pipeline riceve `409` perché un deploy è già in corso.

### Oppure usa la CLI

La [CLI di Vimonto Deploy](https://ops.vimonto.com/docs/it/more/cli) racchiude queste richieste in un solo comando: `deploy deploy shop.example.com --watch` avvia il deploy, segue il task ed esce con il suo risultato. Nella CI legge il token da `DEPLOY_TOKEN`.

### Oppure usa l'URL di deploy

Se ti basta avviare un deploy, l'**URL di deploy** segreto del sito è più semplice: un solo `POST` senza token e niente da seguire. Però non dice alla tua pipeline se il deploy è riuscito. Vedi [deploy](https://ops.vimonto.com/docs/it/sites/deployments).

## Domande frequenti

### Un token è legato a una sola organizzazione?

No. Un token raggiunge ogni organizzazione di cui sei membro, con il tuo ruolo in ciascuna. `GET /user` le elenca. Crea un account separato se una pipeline deve raggiungere una sola organizzazione.

### Cosa succede ai miei token quando cambia il mio ruolo?

Un token segue sempre il tuo ruolo attuale e il tuo accesso ai server. Quando perdi un permesso o lasci un'organizzazione, anche il token lo perde, subito.

### Posso creare server o siti tramite l'API?

Non ancora. L'API copre la lettura di server, siti, deploy, database, backup, ricette e task; il deploy; la creazione e la rimozione di database; e l'esecuzione di backup e ricette.

### Dove trovo l'ID del server e del sito?

Nella barra degli indirizzi dell'app: nelle pagine di un sito l'indirizzo è `/{organization}/servers/{server}/sites/{site}/…`. Anche `GET /orgs/{organization}/servers` e `GET …/servers/{server}/sites` li elencano, e `GET /orgs/{organization}/sites?domain=shop.example.com` trova un sito con l'ID del suo server a partire dal dominio.
