Update snapshot policy
Change the schedule, the retention window, or pause the policy.
Changing interval_minutes re-bases the next run off now.
Authorizations
BASALTIC-HMAC-SHA256 request signing for service-account (access-key) auth.
An AWS-SigV4-style scheme: an HMAC-SHA256 over a canonical request, keyed by a
signing key derived from your secret access key. The basaltic CLI does this
for you; the steps below are for a non-CLI client.
Headers you send
Authorization(this scheme) — format below.X-Date: request time in UTC, compact ISO-8601 basic:YYYYMMDDTHHMMSSZ(e.g.20240115T103000Z). Must be within 5 minutes of server time.X-Nonce: random per-request value (e.g. 16+ bytes of hex). Required — it is what makes each signature unique so the server can reject replays.X-Datealone is not enough (one-second resolution;UNSIGNED-PAYLOADnever enters the canonical request).X-Content-Sha256(optional): lowercase-hex SHA-256 of the request body, to bind the exact bytes to the signature — the server re-hashes and rejects a mismatch. Omit it, and put the literalUNSIGNED-PAYLOADin the body-hash slot, for an empty body or a streaming upload that shouldn't be buffered.
Authorization header format
<date>:YYYYMMDD(the day part of X-Date).<region>: target region code (e.g.sa-saopaulo-1), orglobalfor the region-agnostic (IAM) endpoints.<service>:basaltic.SignedHeaders: the covered header names, lowercased and sorted, joined by;— at minimumhost;x-date;x-nonce(all three required).Signature: lowercase hex from step 4.- Note the
,(comma + space) between the three Authorization parameters.
Step 1 — canonical request
Join these six lines with \n (LF):
canonical-path: the URL-escaped request path (e.g./v1/compute/instances).canonical-query: each query key and value URL-encoded, sorted by key then value, joined by&; empty string when there is no query.canonical-headers: for each signed header,name:value(name lowercased, value trimmed), sorted by name, each followed by a trailing\n.signed-headers: the same names, lowercased, sorted, joined by;.body-hash: lowercase-hex SHA-256 of the body, or the literalUNSIGNED-PAYLOAD.
Step 2 — string to sign
Join with \n:
The second line is the credential date at midnight — NOT the X-Date value — and the third is the credential scope without the access-key id.
Step 3 — derive the signing key (HMAC chain over your secret)
Step 4 — signature
Example (POST with a JSON body)
Request validity
- Valid for 5 minutes from the X-Date timestamp.
- The signature must cover at least
host,x-date, andx-nonce. - Mutating requests (POST/PUT/PATCH/DELETE) that present a signed nonce are
anti-replay guarded for the drift window; omitting
X-Nonceis rejected.
Rate limits
There is no global request budget: a limit applies only where an operation
documents a 429 response, and each such endpoint counts its own fixed
window. Everything else is bounded by quota, not by request rate.
Per-endpoint request limits
A few endpoints are limited in front of the handler, counted per caller —
the authenticated principal when the request carries credentials, the
client IP otherwise. On this API surface that is the public region
catalogue, GET /v1/regions: it guards no secret, and the budget is there
because the catalogue is unauthenticated and database-backed.
An operation that is limited says so by documenting a 429. These
responses — 429 and 2xx — carry the budget, so a client can pace
itself instead of discovering the ceiling by hitting it:
X-RateLimit-Limit— requests allowed per window on this endpoint. Authoritative: read it rather than hard-coding a number.X-RateLimit-Remaining— requests left in the window (0 on a 429).X-RateLimit-Reset— seconds until the window resets. A duration, not a timestamp, so it needs no clock agreement.Retry-After— on a 429 only; seconds to wait. Never zero.
Over the limit the response is 429 with error code RATE_LIMITED. Honor
Retry-After — retrying sooner is refused and extends the window, since
the refused attempt is itself counted.
Service-level limits
Some resources meter the work itself rather than the request, and are
documented on the operation. They return 429 with their own error code
and no rate-limit headers, because the budget is not a per-endpoint window:
sending email is capped per (account, identity) per second
(EMAIL_RATE_LIMIT), and charge attempts are capped per invoice
(INVOICE_PAYMENT_ATTEMPTS_EXHAUSTED).
Path Parameters
Snapshot policy ID
Body
PATCH semantics — an omitted field keeps its current value.
Changing interval_minutes re-bases the next run off now, so
shortening a daily schedule to hourly takes effect within the hour.
1 - 128"nightly"
"Nightly snapshots of the database volume"
false pauses the policy, true resumes it. Pausing stops the
whole policy — no snapshots are taken and none are deleted, so
a paused schedule cannot lose you history. Resuming applies the
retention window again on the next run, so anything sitting
outside it by then — because you lowered retention_count
while paused, say — is reaped on that run.
false
Minutes between snapshots — a minimum gap, not an exact cadence. A
periodic pass takes whatever has come due and re-bases each policy's
next run off the moment it ran, so a snapshot lands at or after
interval_minutes and never before, and can land a minute or two
later when the pass is busy. A window the pass misses costs one
snapshot rather than producing a catch-up burst afterwards.
The floor is one minute, because that pass is what evaluates the
schedule and nothing finer can be honoured; the ceiling is 30 days.
Sub-hourly intervals multiply Ceph snapshot churn and count against
the snapshots quota, so pick the largest interval that meets your
recovery point objective.
1 <= x <= 432001440
How many of this policy's snapshots to keep. When a fire takes the count past this, the oldest go first.
1 <= x <= 2567
Optional age bound, applied on top of retention_count: a
snapshot outside EITHER window is reaped. 0 means no age bound.
The single newest snapshot is exempt from the age bound, so a
volume that could not be snapshotted for longer than the window
never loses its whole history.
0 <= x <= 365030
Response
Snapshot policy updated
A schedule attached to one volume: take a snapshot every
interval_minutes, then keep at most retention_count of the
snapshots this policy created.
Retention only ever deletes snapshots the policy itself created
(those carrying its snapshot_policy_id) — a snapshot taken by
hand is never reaped. It also never deletes a snapshot something
depends on: a snapshot a volume was created from, including a
restore still in progress, is skipped and re-examined later.