curl --request POST \
--url https://storage.{region}.basaltic.sh/v1/snapshot-policies \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"volume": "5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e",
"name": "nightly",
"interval_minutes": 1440,
"retention_count": 7,
"description": "Nightly snapshots of the database volume",
"retention_days": 30,
"enabled": true,
"tags": {
"environment": "production",
"team": "backend"
}
}
'import requests
url = "https://storage.{region}.basaltic.sh/v1/snapshot-policies"
payload = {
"volume": "5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e",
"name": "nightly",
"interval_minutes": 1440,
"retention_count": 7,
"description": "Nightly snapshots of the database volume",
"retention_days": 30,
"enabled": True,
"tags": {
"environment": "production",
"team": "backend"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
volume: '5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e',
name: 'nightly',
interval_minutes: 1440,
retention_count: 7,
description: 'Nightly snapshots of the database volume',
retention_days: 30,
enabled: true,
tags: {environment: 'production', team: 'backend'}
})
};
fetch('https://storage.{region}.basaltic.sh/v1/snapshot-policies', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://storage.{region}.basaltic.sh/v1/snapshot-policies",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'volume' => '5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e',
'name' => 'nightly',
'interval_minutes' => 1440,
'retention_count' => 7,
'description' => 'Nightly snapshots of the database volume',
'retention_days' => 30,
'enabled' => true,
'tags' => [
'environment' => 'production',
'team' => 'backend'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://storage.{region}.basaltic.sh/v1/snapshot-policies"
payload := strings.NewReader("{\n \"volume\": \"5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e\",\n \"name\": \"nightly\",\n \"interval_minutes\": 1440,\n \"retention_count\": 7,\n \"description\": \"Nightly snapshots of the database volume\",\n \"retention_days\": 30,\n \"enabled\": true,\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://storage.{region}.basaltic.sh/v1/snapshot-policies")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"volume\": \"5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e\",\n \"name\": \"nightly\",\n \"interval_minutes\": 1440,\n \"retention_count\": 7,\n \"description\": \"Nightly snapshots of the database volume\",\n \"retention_days\": 30,\n \"enabled\": true,\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://storage.{region}.basaltic.sh/v1/snapshot-policies")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"volume\": \"5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e\",\n \"name\": \"nightly\",\n \"interval_minutes\": 1440,\n \"retention_count\": 7,\n \"description\": \"Nightly snapshots of the database volume\",\n \"retention_days\": 30,\n \"enabled\": true,\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n }\n}"
response = http.request(request)
puts response.read_body{
"snapshot_policy": {
"faults": [
{
"code": "BACKUP_FAILED",
"severity": "error",
"message": "Backup upload failed.",
"details": {},
"first_at": "2023-11-07T05:31:56Z",
"last_at": "2023-11-07T05:31:56Z",
"occurrences": 1
}
],
"id": "3c9f1b2e-6d4a-4e8b-9f1c-2a3b4c5d6e7f",
"crn": "crn:storage:sa-saopaulo-1:my-account:snapshot-policy/nightly",
"volume_id": "5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e",
"name": "nightly",
"description": "Nightly snapshots of the database volume",
"enabled": true,
"interval_minutes": 1440,
"retention_count": 7,
"retention_days": 30,
"next_run_at": "2026-01-16T00:00:00Z",
"last_run_at": "2026-01-15T00:00:00Z",
"tags": {
"environment": "production",
"team": "backend"
},
"created_at": "2026-01-15T09:30:00Z",
"updated_at": "2026-01-15T09:30:00Z"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"params": {
"instances": 2,
"pools": 0
}
}
}{
"error": {
"code": "IDEMPOTENCY_KEY_REUSED",
"message": "This Idempotency-Key was already used with a different request payload",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}Crear una política de instantáneas
Adjuntar una programación de instantáneas a un volumen. Un volumen admite hasta 16 políticas independientes, cada una con su propio intervalo y retención. Las ejecuciones superpuestas crean instantáneas separadas y cada una cuenta para la cuota.
La primera instantánea aterriza en un interval_minutes de ahora — adjuntar un horario no es en sí una solicitud de instantánea. Utilice POST /v1/snapshots para uno ahora.
Qué retención puede eliminar, ya que una programación también es un eliminador automático: solo las instantáneas que esta política misma tomó. Una instantánea tomada a mano nunca se cosecha, y tampoco es una de la que algo dependa: una instantánea de la que se creó un volumen, incluida una restauración que todavía está en ejecución, se omite y se vuelve a ver más tarde. Al pausar la directiva se detiene la eliminación y la toma, y al eliminar la directiva se conservan sus instantáneas existentes. El trabajo ya reclamado antes de que una pausa o eliminación pueda terminar; no se reclaman nuevas eliminaciones de retención después de ese cambio. Otras políticas continúan de forma independiente.
curl --request POST \
--url https://storage.{region}.basaltic.sh/v1/snapshot-policies \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"volume": "5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e",
"name": "nightly",
"interval_minutes": 1440,
"retention_count": 7,
"description": "Nightly snapshots of the database volume",
"retention_days": 30,
"enabled": true,
"tags": {
"environment": "production",
"team": "backend"
}
}
'import requests
url = "https://storage.{region}.basaltic.sh/v1/snapshot-policies"
payload = {
"volume": "5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e",
"name": "nightly",
"interval_minutes": 1440,
"retention_count": 7,
"description": "Nightly snapshots of the database volume",
"retention_days": 30,
"enabled": True,
"tags": {
"environment": "production",
"team": "backend"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
volume: '5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e',
name: 'nightly',
interval_minutes: 1440,
retention_count: 7,
description: 'Nightly snapshots of the database volume',
retention_days: 30,
enabled: true,
tags: {environment: 'production', team: 'backend'}
})
};
fetch('https://storage.{region}.basaltic.sh/v1/snapshot-policies', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://storage.{region}.basaltic.sh/v1/snapshot-policies",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'volume' => '5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e',
'name' => 'nightly',
'interval_minutes' => 1440,
'retention_count' => 7,
'description' => 'Nightly snapshots of the database volume',
'retention_days' => 30,
'enabled' => true,
'tags' => [
'environment' => 'production',
'team' => 'backend'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://storage.{region}.basaltic.sh/v1/snapshot-policies"
payload := strings.NewReader("{\n \"volume\": \"5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e\",\n \"name\": \"nightly\",\n \"interval_minutes\": 1440,\n \"retention_count\": 7,\n \"description\": \"Nightly snapshots of the database volume\",\n \"retention_days\": 30,\n \"enabled\": true,\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://storage.{region}.basaltic.sh/v1/snapshot-policies")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"volume\": \"5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e\",\n \"name\": \"nightly\",\n \"interval_minutes\": 1440,\n \"retention_count\": 7,\n \"description\": \"Nightly snapshots of the database volume\",\n \"retention_days\": 30,\n \"enabled\": true,\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://storage.{region}.basaltic.sh/v1/snapshot-policies")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"volume\": \"5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e\",\n \"name\": \"nightly\",\n \"interval_minutes\": 1440,\n \"retention_count\": 7,\n \"description\": \"Nightly snapshots of the database volume\",\n \"retention_days\": 30,\n \"enabled\": true,\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n }\n}"
response = http.request(request)
puts response.read_body{
"snapshot_policy": {
"faults": [
{
"code": "BACKUP_FAILED",
"severity": "error",
"message": "Backup upload failed.",
"details": {},
"first_at": "2023-11-07T05:31:56Z",
"last_at": "2023-11-07T05:31:56Z",
"occurrences": 1
}
],
"id": "3c9f1b2e-6d4a-4e8b-9f1c-2a3b4c5d6e7f",
"crn": "crn:storage:sa-saopaulo-1:my-account:snapshot-policy/nightly",
"volume_id": "5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e",
"name": "nightly",
"description": "Nightly snapshots of the database volume",
"enabled": true,
"interval_minutes": 1440,
"retention_count": 7,
"retention_days": 30,
"next_run_at": "2026-01-16T00:00:00Z",
"last_run_at": "2026-01-15T00:00:00Z",
"tags": {
"environment": "production",
"team": "backend"
},
"created_at": "2026-01-15T09:30:00Z",
"updated_at": "2026-01-15T09:30:00Z"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"params": {
"instances": 2,
"pools": 0
}
}
}{
"error": {
"code": "IDEMPOTENCY_KEY_REUSED",
"message": "This Idempotency-Key was already used with a different request payload",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}storage:CreateSnapshotPolicy. Consulte permisos de almacenamiento para obtener la lista completa, lo que cubre cada una y un ejemplo de política.Autorizaciones
Un token bearer de OAuth 2.0, enviado como Authorization: Bearer <token>. Esta es la forma recomendada de autenticación.
Obtén el token intercambiando el par de claves de acceso de una cuenta de servicio en POST /v1/oauth/token con grant_type=client_credentials. Es el flujo estándar de credenciales de cliente; las bibliotecas compatibles con OAuth pueden obtener y renovar el token por ti.
curl -s -u "$KEY_ID:$SECRET" -d grant_type=client_credentials \
https://iam.basaltic.sh/v1/oauth/token
Los tokens duran una hora por defecto. El mismo par de claves de acceso también sirve como credencial AWS SigV4 para el endpoint de objetos compatible con S3, que solo acepta ese método de autenticación.
Encabezados
Clave opcional generada por el cliente que hace que una creación sea segura para la reproducción. Al volver a intentar una solicitud con la misma clave, se devuelve el resultado original literalmente en lugar de crear un recurso duplicado. Se rechaza la reutilización de una clave con un cuerpo de solicitud diferente (422); una solicitud cuya clave todavía se está procesando devuelve 409. Los registros se mantienen durante 24 horas. Usa un UUID o un token único similar.
255Cuerpo
UUID, CRN o nombre exacto del volumen de propiedad de la cuenta.
"5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e"
Único dentro de la cuenta: nombra la política en su CRN. Las instantáneas programadas se llaman <policy>-<UTC timestamp>. Los nombres de los recursos no deben comenzar con el prefijo literal crn: ni ser UUID (en cualquier caso, en las formas canónica, compacta, entre corchetes o urn:uuid:).
1 - 128"nightly"
Minutos entre instantáneas: un intervalo mínimo, no una cadencia exacta. Un pase periódico toma lo que haya vencido y re-basea la siguiente ejecución de cada política desde el momento en que se ejecutó, por lo que una instantánea aterriza en o después de interval_minutes y nunca antes, y puede aterrizar un minuto o dos más tarde cuando el pase está ocupado. Una ventana que el pase no consigue cuesta una instantánea en lugar de producir una ráfaga de recuperación después.
El mínimo es de un minuto, porque ese paso es lo que evalúa el horario y nada más fino puede ser honrado; el máximo es de 30 días. snapshots Por lo tanto, elija el intervalo más grande que cumpla con su objetivo de punto de recuperación.
1 <= x <= 432001440
Cuántas instantáneas de esta política se deben conservar. Cuando un incendio lleva la cuenta más allá de esto, el más viejo va primero.
1 <= x <= 2567
"Nightly snapshots of the database volume"
Opcional edad limitada, aplicada encima de retention_count: se recoge una instantánea fuera de la ventana EITHER. 0 significa que no hay edad limitada. La única instantánea más reciente está exenta de la edad limitada, por lo que un volumen que no se pudo instantanear durante más tiempo que la ventana nunca pierde todo su historial.
0 <= x <= 365030
Por defecto es true. Establezca false para adjuntar una programación en pausa. Al pausar, se detiene toda la política: no se toman instantáneas ni se elimina ninguna, porque una programación en pausa que seguía cosechando eliminaría el historial mientras lo estaba viendo.
true
Show child attributes
Show child attributes
{ "environment": "production", "team": "backend" }
Respuesta
Política de instantánea creada
Un programa adjunto a un volumen: tomar una instantánea cada interval_minutes, luego mantener como máximo retention_count de las instantáneas creadas por esta política.
La retención solo elimina las instantáneas que la propia política ha creado (las que llevan su snapshot_policy_id) — una instantánea tomada a mano nunca se recoge. Tampoco elimina nunca una instantánea de la que algo depende: una instantánea de la que se creó un volumen, incluida una restauración todavía en curso, se omite y se vuelve a examinar más tarde.
Show child attributes
Show child attributes

