API
Progetti e token di backup si gestiscono non solo dal portale, ma anche
tramite un'API HTTP — per la vostra automazione o con il
provider Terraform. L'API parla JSON, si trova su
https://api.lionbackup.cloud/api/v1 e applica gli stessi controlli di
autorizzazione del portale.
Creare una chiave
Nel portale, alla voce Sviluppatori, si crea un account di servizio e la relativa chiave API. La chiave viene mostrata una sola volta — conservatela al sicuro.
Un account di servizio ha esattamente i permessi della persona a cui appartiene. Chi nel portale non può creare progetti non può farlo nemmeno tramite l'API; disattivando l'account o cancellando la chiave l'accesso si chiude immediatamente.
Scambiare la chiave con un token di accesso
La chiave non è un bearer token: prima la si scambia con un token di accesso a breve durata (un JWT, valido 15 minuti).
ACCESS_TOKEN=$(curl -s https://authentik.prod.lionbackup.cloud/application/o/token/ \
-d grant_type=client_credentials \
-d client_id=lionbackup-api \
-d client_secret="$LIONBACKUP_API_KEY" \
-d scope="profile lionbackup_api" | jq -r .access_token)
Per lo scambio usate sempre l'host authentik.prod.lionbackup.cloud: il nome
breve authentik.lionbackup.cloud risponde con un reindirizzamento, e un POST
non segue i reindirizzamenti — la chiamata non restituisce quindi alcun token.
Poi lo si invia nell'intestazione Authorization:
API=https://api.lionbackup.cloud/api/v1
curl -s "$API/organizations" -H "Authorization: Bearer $ACCESS_TOKEN"
Per l'ambiente di sviluppo valgono https://api.dev.lionbackup.cloud/api/v1
e https://authentik.dev.lionbackup.cloud/application/o/token/. Una chiave
vale solo nell'ambiente in cui è stata creata.
Passo dopo passo: creare un progetto e un token di backup
Le chiamate seguenti si basano l'una sull'altra e presuppongono ACCESS_TOKEN
e API dalla sezione precedente. Gli identificativi nelle risposte sono
esempi.
1. Interrogare le zone
Un progetto ha bisogno dell'identificativo (UUID) della zona in cui devono
risiedere i suoi dati. Sono prenotabili solo le zone con status = active.
curl -s "$API/zones" -H "Authorization: Bearer $ACCESS_TOKEN"
{
"zones": [
{
"id": "3f0c2a4e-8b1d-4c6a-9e2f-5d7b1a9c0e31",
"name": "de01-1",
"status": "active",
"provider": "Hetzner",
"location_city": "Nürnberg",
"storage_type": "managed object storage"
},
{
"id": "7a9d4b2c-1e5f-4a83-b6c0-2f8e9d1c4a57",
"name": "de01-2",
"status": "preparing",
"provider": "Hetzner",
"location_city": "Falkenstein",
"storage_type": "managed object storage"
}
]
}
L'identificativo della zona desiderata si può salvare direttamente in una variabile:
ZONE_ID=$(curl -s "$API/zones" -H "Authorization: Bearer $ACCESS_TOKEN" \
| jq -r '.zones[] | select(.name == "de01-1") | .id')
2. Determinare l'organizzazione
I progetti appartengono a un'organizzazione. L'elenco mostra ogni
organizzazione di cui siete membri, con il vostro ruolo — possono creare
progetti owner e admin.
curl -s "$API/organizations" -H "Authorization: Bearer $ACCESS_TOKEN"
{
"organizations": [
{
"id": "9b2e6c1a-4d3f-4e8b-a7c5-0f1d2e3a4b5c",
"name": "Example Ltd",
"status": "approved",
"role": "owner"
}
]
}
ORG_ID=$(curl -s "$API/organizations" -H "Authorization: Bearer $ACCESS_TOKEN" \
| jq -r '.organizations[] | select(.name == "Example Ltd") | .id')
La scelta per nome è voluta: l'account di servizio vede tutte le organizzazioni del suo proprietario e l'ordine dell'elenco non è garantito.
3. Creare il progetto
I campi obbligatori sono name (al massimo 100 caratteri) e
availability_zone_id. Sono opzionali alert_email, billing_reference,
immutable_storage (predefinito false) e — solo con archiviazione
immutabile — retention_days (da 1 a 365, predefinito 30).
curl -s -X POST "$API/organizations/$ORG_ID/projects" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"name\":\"web-servers\",\"availability_zone_id\":\"$ZONE_ID\",\"alert_email\":\"ops@example.com\"}"
Risposta con stato 201:
{
"project": {
"id": "ea1296ad-5c7b-4f2e-8a1d-3b6c9e0f7d24",
"name": "web-servers",
"status": "active",
"organization_id": "9b2e6c1a-4d3f-4e8b-a7c5-0f1d2e3a4b5c",
"availability_zone_id": "3f0c2a4e-8b1d-4c6a-9e2f-5d7b1a9c0e31",
"alert_email": "ops@example.com",
"billing_reference": null,
"immutable_storage": false,
"retention_days": null,
"created_at": "2026-09-24 09:41:12.418273"
}
}
PROJECT_ID=ea1296ad-5c7b-4f2e-8a1d-3b6c9e0f7d24
4. Creare un token di backup
Un token di backup appartiene esattamente a un progetto. Con type = write
il client esegue i backup, con type = read esegue i ripristini. Senza
indicazione viene creato un token di scrittura per Linux; operating_system
conosce Linux, Windows e macOS. Opzionalmente usage_count_limit,
rate_limit_per_minute e rate_limit_per_hour limitano l'uso.
curl -s -X POST "$API/projects/$PROJECT_ID/tokens" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"write","operating_system":"Linux"}'
Risposta con stato 201:
{
"token": {
"id": "c4d1e8f2-6a3b-4c9d-8e7f-1a2b3c4d5e6f",
"type": "write",
"secret": "9f3e7b1c…a41c"
}
}
secret è il vero e proprio token di backup (128 caratteri esadecimali).
Viene consegnato una sola volta e non può più essere recuperato in seguito —
la piattaforma conserva solo un hash. Salvatelo subito nel vostro gestore di
segreti.
Un token di lettura per i ripristini si crea allo stesso modo:
curl -s -X POST "$API/projects/$PROJECT_ID/tokens" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"read"}'
{
"token": {
"id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
"type": "read",
"secret": "d27c0a8e…5b93"
}
}
5. Elencare i token
L'elenco contiene solo metadati — mai un segreto. I token revocati non compaiono più.
curl -s "$API/projects/$PROJECT_ID/tokens" -H "Authorization: Bearer $ACCESS_TOKEN"
{
"tokens": [
{
"id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
"type": "read",
"operating_system": "Linux",
"is_active": true,
"usage_count": 0,
"usage_count_limit": null,
"created_at": "2026-09-24 09:43:05.102944",
"expire": null
},
{
"id": "c4d1e8f2-6a3b-4c9d-8e7f-1a2b3c4d5e6f",
"type": "write",
"operating_system": "Linux",
"is_active": true,
"usage_count": 0,
"usage_count_limit": null,
"created_at": "2026-09-24 09:42:37.556210",
"expire": null
}
]
}
6. Revocare un token
TOKEN_ID=c4d1e8f2-6a3b-4c9d-8e7f-1a2b3c4d5e6f
curl -s -X DELETE "$API/projects/$PROJECT_ID/tokens/$TOKEN_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"
{ "deleted": true }
7. Chiudere il progetto
Un progetto non viene cancellato, ma chiuso: lo stato passa a closing, tutti
i token di scrittura vengono revocati immediatamente e la risposta ne indica il
numero. La chiamata è idempotente — un progetto già chiuso risponde di nuovo
con 200.
curl -s -X POST "$API/projects/$PROJECT_ID/close" \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"project": {
"id": "ea1296ad-5c7b-4f2e-8a1d-3b6c9e0f7d24",
"name": "web-servers",
"status": "closing",
"organization_id": "9b2e6c1a-4d3f-4e8b-a7c5-0f1d2e3a4b5c",
"availability_zone_id": "3f0c2a4e-8b1d-4c6a-9e2f-5d7b1a9c0e31",
"alert_email": "ops@example.com",
"billing_reference": null,
"immutable_storage": false,
"retention_days": null,
"created_at": "2026-09-24 09:41:12.418273"
},
"write_tokens_revoked": 1
}
Cosa è bene sapere
Permessi per azione
L'API verifica gli stessi ruoli del portale:
| Azione | Ruolo |
|---|---|
| Leggere il progetto, elencare i token | qualsiasi ruolo nel progetto |
| Modificare il progetto, creare token | owner, admin, writer |
| Revocare token | owner, admin |
| Creare il progetto, chiudere il progetto | owner o admin dell'organizzazione |
404 invece di 403
Una risorsa che non esiste e una su cui non avete alcun ruolo rispondono allo
stesso modo: 404 con {"error":"not_found"}. Così l'API non rivela quali
identificativi esistono. Un 403 con permission_denied lo ricevete solo se
potete vedere la risorsa ma non eseguire l'azione.
La pubblicazione verso la zona è asincrona
Un nuovo token viene trasmesso alla Storage Zone dopo la creazione. Finché ciò
non è avvenuto, la zona rifiuta il token con 401 — di norma questione di
secondi, in caso di guasto fino alla successiva sincronizzazione. In tal caso
non create di nuovo il token, ma riprovate più tardi. Al contrario, un
token revocato può restare valido nella zona ancora per poco.
Chiusura di un progetto
La chiusura revoca immediatamente tutti i token di scrittura e porta il
progetto in closing. I token di lettura restano validi per il periodo di
conservazione e, finché un backup è ancora entro il suo periodo di
conservazione, potete anche creare nuovi token di lettura per continuare a
ripristinare i backup archiviati. Un progetto closing rifiuta nuovi token di
scrittura (409 project_closed); una volta closed non accetta più alcun
token. Allo stesso modo un'organizzazione chiusa rifiuta nuovi progetti (409 organization_closed).
Limiti di frequenza
| Limite | Valore | Vale per |
|---|---|---|
| Richieste per indirizzo IP | 60/minuto | ogni richiesta all'API |
| Richieste per account di servizio | 60/minuto | ogni richiesta autenticata |
| Dimensione di una richiesta | 1 MB | il contenuto inviato |
Ogni risposta autenticata riporta X-RateLimit-Limit,
X-RateLimit-Remaining e X-RateLimit-Reset (tempo Unix in cui termina la
finestra di un minuto in corso). Oltre il limite l'API risponde 429 con
{"error":"rate_limited"} e l'intestazione Retry-After — attendete quei
secondi e ripetete la richiesta. Il provider Terraform lo fa da solo.
Le intestazioni X-RateLimit-* possono mancare: se la cache dei contatori
della piattaforma non è disponibile, l'API temporaneamente non conta per
account di servizio e quindi non annuncia nemmeno un budget. Nella vostra
automazione affidatevi allo stato 429 e a Retry-After, non alle
intestazioni.
Formato degli errori
Ogni errore è un oggetto JSON con esattamente un campo: {"error":"<code>"}.
Il codice è stabile e pensato per i programmi; diramate in base a esso, non
solo in base allo stato HTTP.
| Stato | Codice | Significato |
|---|---|---|
400 | invalid_request | il contenuto non è JSON, manca un campo obbligatorio o un valore non è valido |
400 | invalid_zone | availability_zone_id è sconosciuto o la zona non è active |
400 | retention_out_of_range | retention_days è fuori dall'intervallo da 1 a 365 |
401 | invalid_token | token di accesso mancante, non valido o scaduto, account di servizio cancellato |
403 | owner_inactive | la persona a cui appartiene l'account di servizio è disattivata |
403 | permission_denied | il vostro ruolo non consente questa azione |
404 | not_found | risorsa sconosciuta o non visibile per voi |
405 | method_not_allowed | il percorso esiste, il metodo HTTP no |
409 | organization_closed | l'organizzazione è in chiusura o è chiusa |
409 | project_closed | il progetto è closed, oppure closing ed è stato richiesto un token di scrittura |
429 | rate_limited | limite di frequenza — rispettare Retry-After |
500 | internal_error | errore imprevisto sulla piattaforma |
503 | service_unavailable | temporaneamente non disponibile — riprovare più tardi |
Terraform
Per Terraform e OpenTofu esiste un provider che usa la stessa API e gestisce progetti e token di backup come risorse. Fonte di distribuzione, configurazione e un esempio completo si trovano nella pagina Terraform.
Riferimento
La specifica completa è disponibile come documento OpenAPI 3.1:
openapi.yaml. La stessa API la pubblica su
/api/v1/openapi.yaml — descrive quindi sempre esattamente la versione in
esecuzione.
Loading the API reference…