From c7c0d8799327915adc7bbef03ec699325ee0d83e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 13:31:05 -0700 Subject: [PATCH 001/250] First draft for SLA documentation --- host/hosting-overview.mdx | 1 + host/sla-backtester.mdx | 221 +++++++++++++++++++++++++++++ host/sla-offers.mdx | 167 ++++++++++++++++++++++ snippets/host/cli/list-machine.mdx | 12 ++ snippets/host/sdk/list-machine.mdx | 17 ++- 5 files changed, 417 insertions(+), 1 deletion(-) create mode 100644 host/sla-backtester.mdx create mode 100644 host/sla-offers.mdx diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 5c180d2f..f14faa29 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -47,6 +47,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) - the offer end date, which determines how long the offer accepts new rental contracts +- optional [SLA (reliability guarantee)](/host/sla-offers) parameters — reliability target, claim, and confidence The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx new file mode 100644 index 00000000..916e136b --- /dev/null +++ b/host/sla-backtester.mdx @@ -0,0 +1,221 @@ +--- +title: "SLA Earnings Backtester" +description: "Replay your machine's historical earnings through SLA math to preview premiums and payouts before listing." +"canonical": "/host/sla-backtester" +--- + +The **SLA earnings backtester** lets you answer a practical question before you list: *if I had offered SLA at reliability **R** with confidence **P**, how would that have affected my earnings on this machine over the last few months?* + +It replays your machine's **real historical compute earnings and uptime** through the same v5 SLA math used in production settlement, then compares the simulated result to what you actually earned from SLA (if anything). + + +The backtester is available through the API only. You must own the machine and use an API key with **`machine_read`** permission. + + +## When to use it + +Use the backtester before you enable SLA on a listing, or when you want to tune parameters: + +- **Pick a reliability target** — see how often you would have kept premiums vs paid out +- **Compare confidence levels** — tighter confidence means higher premiums for clients but more risk to you if uptime slips +- **Stress-test bad weeks** — use the optional flat uptime override to see payout size if reliability dropped +- **Compare to history** — each day includes `historical_sla`, your machine's realized SLA earnings in that period (zero if you were not offering SLA) + +For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). + +## How it works + +1. You choose a machine, date range, reliability target (`r`), and confidence (`p`). +2. The API loads per-day earnings from your machine's history (`machine_earns`). +3. For each active day, it computes GPU, storage, and bandwidth earnings plus simulated SLA host earnings. +4. It returns a day-by-day breakdown and summary totals. + +**Simulated vs listing parameters.** In the backtester, reliability target and claim are both set to **`r`**. When you actually list a machine, you can set **`sla_r_claim` above `sla_r_target`** for lower client premiums. The backtester is conservative: it shows the economics when target and claim match. + +**Active vs idle days.** Days with no rental activity (zero compute delta) appear in the results as zero-filled rows but do not count toward `covered_days`. Only days with actual earnings are replayed through SLA math. + +## API reference + +``` +GET /api/v0/host/sla_backtest/ +``` + +Requires Bearer authentication. Rate limited like other host API endpoints. + +### Query parameters + +| Parameter | Required | Description | +| --- | --- | --- | +| `machine_id` | Yes | ID of your machine | +| `r` | Yes | Reliability target to simulate (0–1). Used as both target and claim. Example: `0.95` = 95%. | +| `p` | No | Host confidence (0–1). Maps to the same spread used when listing with `sla_sigma_x`. Default: ~0.67 (normal confidence). | +| `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | +| `end_date` | No | Range end as Unix epoch seconds. Default: now. | +| `reliability` | No | Optional flat uptime override (0–1) for all replayed days. Ignores historical uptime — useful for what-if analysis ("what if every day had 90% uptime?"). | + +### Limits + +| Limit | Value | +| --- | --- | +| Default lookback | 90 days | +| Maximum range | 366 days (inclusive) | +| Ownership | Must own the machine | + +### Example request + +```bash +curl -s -H "Authorization: Bearer YOUR_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.67&start_date=1704067200&end_date=1711929600" +``` + +Compare two confidence levels on the same history: + +```bash +# Normal confidence (~67%) +curl -s -H "Authorization: Bearer YOUR_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.67" + +# High confidence (~83%) — tighter spread, lower simulated premiums +curl -s -H "Authorization: Bearer YOUR_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.83" +``` + +Stress-test with flat 90% uptime: + +```bash +curl -s -H "Authorization: Bearer YOUR_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.67&reliability=0.90" +``` + +## Reading the response + +A successful response looks like this (fields abbreviated): + +```json +{ + "success": true, + "machine_id": 12345, + "has_data": true, + "start_day": 19723, + "end_day": 19812, + "covered_days": 45, + "skipped_days": 45, + "reliability": 0.998500, + "fleet_reliability": 0.991200, + "params": { + "r": 0.95, + "p": 0.6667, + "sigma_x": 0.5, + "reliability": null + }, + "daily_results": [ + { + "day": 19723, + "gpu": 84.0, + "storage": 2.4, + "bandwidth": 0.1, + "uptime": 1.0, + "sla": 0.18, + "historical_sla": 0.0 + } + ], + "summary": { + "total_gpu": 3780.0, + "total_storage": 108.0, + "total_bandwidth": 4.5, + "total_sla": 8.1, + "total_earnings": 3900.6, + "total_historical_sla": 0.0, + "worst_day_loss": 42.0 + } +} +``` + +### Top-level fields + +| Field | Meaning | +| --- | --- | +| `has_data` | `true` if at least one day in the range had earnings to replay | +| `covered_days` | Days with rental activity replayed through SLA math | +| `skipped_days` | Days in the range with no activity (zero-filled in `daily_results`) | +| `reliability` | Actual uptime ratio over the range (`total uptime / total active time`) | +| `fleet_reliability` | Average reliability across your other machines (context only) | + +### Per-day fields (`daily_results`) + +| Field | Meaning | +| --- | --- | +| `gpu`, `storage`, `bandwidth` | That day's compute earnings breakdown ($) | +| `uptime` | Uptime fraction for the day (0–1), or your flat override if set | +| `sla` | **Simulated SLA host earnings** for the day. Positive = you keep premium; negative = you pay the client | +| `historical_sla` | What you **actually** earned from SLA that day (signed). Zero if you were not offering SLA | + +Plot `sla` over time to see which days would have helped or hurt under the chosen parameters. Compare against `historical_sla` to see how simulated economics differ from reality. + +### Summary fields + +| Field | Meaning | +| --- | --- | +| `total_gpu`, `total_storage`, `total_bandwidth` | Compute earnings over covered days | +| `total_sla` | Net simulated SLA earnings. Positive = SLA would have added income overall | +| `total_earnings` | Compute + simulated SLA | +| `total_historical_sla` | Sum of realized historical SLA in the range | +| `worst_day_loss` | Largest single-day client payout (your worst simulated loss) | + +## Interpreting results + +### Mostly positive `sla` values + +Your historical uptime was strong relative to the target. SLA would likely have been a net positive — small premiums on good days, few payout days. + +### Negative `sla` on specific days + +Those days had uptime below your chosen target. The magnitude shows how much you would have paid out. If you see clusters of negative days, consider a lower target, wider confidence, or fixing reliability before listing SLA. + +### `total_sla` near zero + +Break-even territory — premiums and payouts roughly balance. Typical when your actual uptime matches your stated target. + +### `total_sla` strongly negative + +Under the simulated parameters, SLA would have cost you money over this window. Either improve uptime, lower the target, or widen confidence before listing. + +### Using `reliability` override + +Setting `reliability=0.90` while keeping `r=0.99` answers: *if every active day had 90% uptime, how bad would SLA payouts get?* Use this to understand tail risk before committing to a high target. + +## Confidence values (`p`) + +The backtester accepts **`p`** (confidence) instead of `sla_sigma_x`. They map to the same presets used when listing: + +| Confidence `p` | Approx. label | Listing equivalent | +| --- | --- | --- | +| `0.83` | High | `sla_sigma_x ≈ 0.2` | +| `0.67` | Normal (default) | `sla_sigma_x ≈ 0.5` | +| `0.50` | Wide | `sla_sigma_x ≈ 1.0` | + +Higher confidence (higher `p`) → tighter spread → lower premiums for clients, but less room for uptime to slip before payouts. + +## Error responses + +| HTTP | `error` | Cause | +| --- | --- | --- | +| 400 | `invalid_range` | `start_date` is after `end_date` | +| 400 | `range_too_large` | More than 366 days requested | +| 400 | `invalid_params` | Invalid `r`, `p`, or other SLA parameter | +| 403 | `not_owner` | Machine belongs to another host | +| 404 | `machine_not_found` | Invalid `machine_id` | + +## Recommended workflow + +1. **Run a baseline backtest** on a machine with at least a few weeks of rental history. Use your intended target and normal confidence (`p=0.67`). +2. **Check `worst_day_loss`** — can you absorb that payout from a bad day? +3. **Try a higher target** (for example `r=0.99`) and see how `total_sla` changes. +4. **Run a stress test** with `reliability=0.90` at your intended target. +5. **List with headroom** — set `sla_r_claim` above `sla_r_target` on the actual offer for better client pricing than the backtester shows (see [SLA Offers](/host/sla-offers)). + +## Related documentation + +- [SLA Offers](/host/sla-offers) — listing parameters, economics, and risk scenarios +- [SLA Coverage (clients)](/guides/instances/choosing/sla-coverage) — how clients search and pay for SLA +- [API permissions](/api-reference/permissions) — `machine_read` scope required diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx new file mode 100644 index 00000000..89090e27 --- /dev/null +++ b/host/sla-offers.mdx @@ -0,0 +1,167 @@ +--- +title: "SLA Offers" +description: "Offer reliability guarantees on your machines, set SLA parameters, and understand how premiums and payouts work." +"canonical": "/host/sla-offers" +--- + +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is reliability insurance: the client pays a small daily premium, and if uptime falls short of the agreed target, the client receives a payout from your earnings. + +This page explains how SLA offers work from the host side — what you are promising, how pricing is calculated, and what happens when uptime is good or bad. + + +SLA settlement uses the **v5 asymmetric insurance model**. Premiums and payouts are settled daily based on measured uptime. + + +## How it works (plain English) + +Think of an SLA offer as three linked ideas: + +1. **Reliability target** — the uptime level the listing is priced around (for example, 95% or 99%). +2. **Your reliability claim** — what you believe your machine will actually deliver. +3. **Your confidence** — how sure you are about that claim. A tight confidence means you stand behind a narrow range; a wide confidence means you admit more uncertainty and clients pay a higher premium. + +When a client rents with SLA enabled: + +- They pay **compute** (GPU, storage, bandwidth) plus a **daily SLA premium**. +- Each day, Vast measures how long the instance was online and settles the SLA. +- **Good uptime** → you keep the premium for that day. +- **Bad uptime** → you pay the client from your earnings (up to the day's compute charges plus premium). + +Under honest pricing, a host who delivers what they claim should roughly break even on SLA over time — premiums balance payouts. + +## SLA parameters + +When you list or update a machine, you can set these fields on the offer (via the host console or the [list machine API](/api-reference/machines/list-machine)): + +| Parameter | API field | What it means | +| --- | --- | --- | +| Reliability target | `sla_r_target` | The coverage level baked into the offer. Set above `0` to enable SLA. Values are fractions between 0 and 1 (for example, `0.95` = 95%). Legacy alias: `sla_reliability`. | +| Reliability claim | `sla_r_claim` | Your advertised belief about machine uptime. Defaults to the reliability target if omitted. Must be **≥** the target. | +| Confidence spread | `sla_sigma_x` | How wide your belief is around the claim. Lower = more confident (cheaper for clients). Defaults to `0.5` if omitted. | + +### Confidence presets + +If you prefer thinking in confidence rather than `sla_sigma_x`, these presets match the shipped defaults: + +| Label | Approx. confidence | `sla_sigma_x` | Effect on premium | +| --- | --- | --- | --- | +| High | ~83% | `0.2` | Lowest premiums — you are very sure about your claim | +| Normal (default) | ~67% | `0.5` | Balanced default | +| Wide | 50% | `1.0` | Higher premiums — more uncertainty priced in | + +### Validation rules + +Offers with invalid combinations are rejected at listing time: + +- Reliability target and claim must be between 0 and 1 (exclusive of 0 for target). +- **Target cannot exceed claim** — you cannot promise coverage above what you claim you can deliver. +- Confidence spread must be positive and at most `3.0`. + +## Listing an SLA offer + +### Web console + +When listing a machine in the [host machines page](https://cloud.vast.ai/host/machines), enable SLA and set your reliability target, claim, and confidence. The console shows how these affect the premium clients will see. + +### CLI and API + +Pass SLA fields to `vastai list machine` or `PUT /api/v0/machines/create_asks/`: + +```bash +vastai list machine 12345 \ + --price_gpu 3.50 \ + --sla_r_target 0.95 \ + --sla_r_claim 0.99 \ + --sla_sigma_x 0.5 +``` + +Minimal example (claim and confidence use defaults): + +```json +{ + "machine": 12345, + "price_gpu": 3.50, + "sla_r_target": 0.95 +} +``` + +This creates an offer with target `0.95`, claim `0.95`, and confidence spread `0.5`. + + +Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. + + +## Economics walkthrough + +**Setup:** You list an H100 at **$3.50/hr** GPU price with target **95%**, claim **99%**, and normal confidence (`sla_sigma_x = 0.5`). + +| Item | Amount | +| --- | --- | +| Daily compute (`C`) | ~$84/day ($3.50 × 24 hr) | +| SLA premium to client | ~**$0.008/hr** (~$0.20/day) | + +This premium is what a client searching for 95% reliability would see added to `dph_total`. + +### If you meet your claim + +| Measured uptime (simplified) | Client net (per day) | You net (per day) | +| --- | --- | --- | +| ~100% (excellent day) | −$0.20 (paid premium) | +$0.20 (keep premium) | +| ~99% (good day) | −$0.17 | +$0.17 | + +You keep most or all of the premium. + +### If you miss the target + +Settlement uses a **blend of recent and historical uptime** (not just a single day's raw percentage), but the direction is the same — worse uptime means larger client payouts: + +| Measured uptime (simplified) | Client net (per day) | You net (per day) | +| --- | --- | --- | +| At target (~95%) | ~+$42 | ~−$42 | +| Well below target (~90% or less) | ~+$84 (full compute refund) | ~−$84 | + +On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged twice for downtime they already did not pay for. + + +These examples use simplified single-day uptime for illustration. Production settlement aggregates uptime across multiple time windows (from about 1 day to about 3 years of history), so one bad hour does not always produce the maximum payout, and one good day does not instantly erase a long streak of problems. + + +## Risk scenarios + +### You claim 99% but deliver 99.5% + +You outperform your claim. Clients pay small premiums; payouts are rare. You net positive on SLA over time. + +### You claim 99% but have an offline day + +Clients receive payouts tied to how far measured uptime falls below the target. Extended outages can approach a full-day compute refund. Your reliability score and verification status may also be affected separately from SLA settlement. + +### You set target equal to claim (for example, both 95%) + +Premiums are **much higher** because you are not offering any headroom below your claim. Clients only buy this when they need coverage exactly at your stated level. Prefer setting **claim above target** (for example, claim 99%, target 95%) for competitive premiums. + +### You widen confidence (`sla_sigma_x` → 1.0) + +Clients pay more because you admit greater uncertainty. Use this if your uptime history is volatile or the machine is new. + +### Scheduled maintenance + +Maintenance windows that were scheduled with sufficient notice may be credited back toward uptime, reducing SLA penalties for planned downtime. Unplanned outages count fully. + +## Preview earnings before listing + +Use the [SLA Earnings Backtester](/host/sla-backtester) to replay your machine's historical earnings through SLA math and compare simulated premiums and payouts before you enable SLA on a listing. + +## Tips for competitive SLA offers + +- **Set claim above target.** A claim of 99% with a target of 95% produces a much lower premium than matching them both at 95%. +- **Tighten confidence only when earned.** Use high confidence (`sla_sigma_x ≈ 0.2`) after you have a strong uptime track record on that machine. +- **Keep the machine online during active contracts.** SLA payouts and verification are separate systems, but both respond to downtime. +- **Use the [SLA backtester](/host/sla-backtester)** to preview how different targets and confidence levels would have affected past earnings. + +## Related documentation + +- [SLA Earnings Backtester](/host/sla-backtester) — preview SLA economics on historical earnings +- [SLA Coverage for Clients](/guides/instances/choosing/sla-coverage) — how clients search, compare, and benefit from SLA offers +- [Hosting Overview](/host/hosting-overview) — offers, rental contracts, and listing basics +- [Understanding Verification](/host/understanding-verification) — platform verification (separate from SLA, but related to trust) diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 1c385fd7..4a066b81 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -60,6 +60,18 @@ vastai list machine ID [options] Price for disk on volume contract offer. Defaults to price_disk. Invalid if vol_size is 0. (alias: `--vol_price`) + + Client reliability coverage target (0–1). Values above 0 enable SLA on the offer. Legacy alias: `--sla_reliability`. (alias: `--sla-r-target`) + + + + Host reliability claim (0–1). Must be ≥ `sla_r_target`. Defaults to `sla_r_target` if omitted. (alias: `--sla-r-claim`) + + + + Host belief spread in log-failure space (0–3]. Lower = tighter confidence and lower client premiums. Defaults to `0.5`. (alias: `--sla-sigma-x`) + + ## Description Performs the same action as pressing the "LIST" button on the site https://cloud.vast.ai/host/machines. diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index a67e8bef..4ef27387 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -13,7 +13,10 @@ VastAI.list_machine( price_inetd: Optional[float] = None, discount_rate: Optional[float] = None, min_chunk: Optional[int] = None, - end_date: Optional[str] = None + end_date: Optional[str] = None, + sla_r_target: Optional[float] = None, + sla_r_claim: Optional[float] = None, + sla_sigma_x: Optional[float] = None, ) -> str ``` @@ -51,6 +54,18 @@ VastAI.list_machine( end_date + + Reliability coverage target (0–1). Values above 0 enable SLA. + + + + Host reliability claim (0–1). Must be ≥ sla_r_target. + + + + Host confidence spread (0–3]. Lower = tighter confidence. + + ## Returns `str`, Result from the API call. From 36aa7ac0d96ed913dcaf9e551adcfc3bd04c6363 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 14:14:36 -0700 Subject: [PATCH 002/250] Address doc-review feedback for host SLA documentation. Register SLA pages in nav, align OpenAPI with listing/backtester endpoints, and fix clarity issues flagged across all-hosts review (confidence direction, broken links, jargon, onboarding gaps). Co-authored-by: Cursor --- api-reference/openapi.yaml | 165 ++++++++++++++++++- api-reference/openapi/yaml/list_machine.yaml | 24 ++- api-reference/openapi/yaml/sla_backtest.yaml | 149 +++++++++++++++++ api-reference/permissions.mdx | 1 + docs.json | 2 + host/hosting-overview.mdx | 4 +- host/sla-backtester.mdx | 25 ++- host/sla-offers.mdx | 26 +-- snippets/host/cli/list-machine.mdx | 4 +- snippets/host/sdk/list-machine.mdx | 15 +- 10 files changed, 386 insertions(+), 29 deletions(-) create mode 100644 api-reference/openapi/yaml/sla_backtest.yaml diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 5f36a511..fd677de1 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4499,7 +4499,8 @@ paths: description: 'Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. - Allows setting pricing, minimum GPU requirements, end date and discount rates. + Allows setting pricing, minimum GPU requirements, end date, discount rates, + and SLA parameters. CLI Usage: `vastai list machine [options]`' @@ -4549,6 +4550,27 @@ paths: type: number format: float description: Maximum discount rate allowed for prepaid credits + sla_r_target: + type: number + format: float + description: "Client reliability coverage target (0\u20131). Values\ + \ above 0 enable SLA on the offer.\nLegacy alias: sla_reliability.\n" + sla_r_claim: + type: number + format: float + description: "Host reliability claim (0\u20131). Must be greater\ + \ than or equal to sla_r_target.\nDefaults to sla_r_target if\ + \ omitted.\n" + sla_sigma_x: + type: number + format: float + description: "Host confidence spread \u2014 how wide your belief\ + \ is around the claim.\nMust be greater than 0 and at most 3.0.\ + \ Defaults to 0.5.\n" + sla_reliability: + type: number + format: float + description: Legacy alias for sla_r_target. responses: '200': description: Successful response @@ -8989,6 +9011,147 @@ paths: tags: - Accounts operationId: showUser + /api/v0/host/sla_backtest: + get: + summary: sla backtest + description: 'Replays a machine''s historical compute earnings and uptime through + SLA settlement math + + to preview premiums and payouts before listing with SLA. + + + Requires `machine_read` permission. See [SLA Earnings Backtester](/host/sla-backtester) + for usage guide.' + security: + - BearerAuth: [] + parameters: + - name: machine_id + in: query + required: true + schema: + type: integer + description: ID of your machine. + - name: r + in: query + required: true + schema: + type: number + format: float + minimum: 0 + exclusiveMinimum: true + maximum: 1 + description: "Reliability target to simulate (0\u20131). Used as both target\ + \ and claim." + - name: p + in: query + schema: + type: number + format: float + minimum: 0 + exclusiveMinimum: true + maximum: 1 + default: 0.6667 + description: "Host confidence (0\u20131). Maps to sla_sigma_x when listing.\ + \ Default 0.6667 (normal)." + - name: start_date + in: query + schema: + type: integer + description: Range start as Unix epoch seconds. Default is 90 days before + end_date. + - name: end_date + in: query + schema: + type: integer + description: Range end as Unix epoch seconds. Default is now. + - name: reliability + in: query + schema: + type: number + format: float + minimum: 0 + maximum: 1 + description: "Optional flat uptime override (0\u20131) for all replayed days." + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + machine_id: + type: integer + has_data: + type: boolean + description: false when no days in the range had earnings to replay. + start_day: + type: integer + description: UTC day index (days since 1970-01-01). + end_day: + type: integer + description: UTC day index (days since 1970-01-01). + covered_days: + type: integer + skipped_days: + type: integer + reliability: + type: number + format: float + fleet_reliability: + type: number + format: float + params: + type: object + daily_results: + type: array + items: + type: object + summary: + type: object + '400': + description: Bad Request + content: + application/json: + schema: + type: object + properties: + error: + type: string + enum: + - invalid_range + - range_too_large + - bad_request + - invalid_params + msg: + type: string + '403': + description: "Forbidden \u2014 not machine owner" + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: not_owner + '404': + description: Machine not found + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: machine_not_found + '429': + description: "Too Many Requests \u2014 rate limit exceeded" + tags: + - Host + operationId: slaBacktest /api/v0/deployment/{id}/start: post: summary: start deployment diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 9b35c946..5debd88f 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -12,7 +12,7 @@ paths: summary: list machine description: | Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. - Allows setting pricing, minimum GPU requirements, end date and discount rates. + Allows setting pricing, minimum GPU requirements, end date, discount rates, and SLA parameters. CLI Usage: `vastai list machine [options]` security: @@ -61,6 +61,28 @@ paths: type: number format: float description: Maximum discount rate allowed for prepaid credits + sla_r_target: + type: number + format: float + description: | + Client reliability coverage target (0–1). Values above 0 enable SLA on the offer. + Legacy alias: sla_reliability. + sla_r_claim: + type: number + format: float + description: | + Host reliability claim (0–1). Must be greater than or equal to sla_r_target. + Defaults to sla_r_target if omitted. + sla_sigma_x: + type: number + format: float + description: | + Host confidence spread — how wide your belief is around the claim. + Must be greater than 0 and at most 3.0. Defaults to 0.5. + sla_reliability: + type: number + format: float + description: Legacy alias for sla_r_target. responses: '200': description: Successful response diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml new file mode 100644 index 00000000..37a6e7a1 --- /dev/null +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -0,0 +1,149 @@ +openapi: 3.0.0 +info: + title: Vast.ai API - SLA Backtest + description: Replay historical machine earnings through SLA settlement math. + version: 1.0.0 +servers: +- url: https://console.vast.ai + description: Production server +paths: + /api/v0/host/sla_backtest/: + get: + summary: sla backtest + description: | + Replays a machine's historical compute earnings and uptime through SLA settlement math + to preview premiums and payouts before listing with SLA. + + Requires `machine_read` permission. See [SLA Earnings Backtester](/host/sla-backtester) for usage guide. + security: + - BearerAuth: [] + parameters: + - name: machine_id + in: query + required: true + schema: + type: integer + description: ID of your machine. + - name: r + in: query + required: true + schema: + type: number + format: float + minimum: 0 + exclusiveMinimum: true + maximum: 1 + description: Reliability target to simulate (0–1). Used as both target and claim. + - name: p + in: query + schema: + type: number + format: float + minimum: 0 + exclusiveMinimum: true + maximum: 1 + default: 0.6667 + description: Host confidence (0–1). Maps to sla_sigma_x when listing. Default 0.6667 (normal). + - name: start_date + in: query + schema: + type: integer + description: Range start as Unix epoch seconds. Default is 90 days before end_date. + - name: end_date + in: query + schema: + type: integer + description: Range end as Unix epoch seconds. Default is now. + - name: reliability + in: query + schema: + type: number + format: float + minimum: 0 + maximum: 1 + description: Optional flat uptime override (0–1) for all replayed days. + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + machine_id: + type: integer + has_data: + type: boolean + description: false when no days in the range had earnings to replay. + start_day: + type: integer + description: UTC day index (days since 1970-01-01). + end_day: + type: integer + description: UTC day index (days since 1970-01-01). + covered_days: + type: integer + skipped_days: + type: integer + reliability: + type: number + format: float + fleet_reliability: + type: number + format: float + params: + type: object + daily_results: + type: array + items: + type: object + summary: + type: object + '400': + description: Bad Request + content: + application/json: + schema: + type: object + properties: + error: + type: string + enum: + - invalid_range + - range_too_large + - bad_request + - invalid_params + msg: + type: string + '403': + description: Forbidden — not machine owner + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: not_owner + '404': + description: Machine not found + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: machine_not_found + '429': + description: Too Many Requests — rate limit exceeded + tags: + - Host +components: + securitySchemes: + BearerAuth: + type: http + scheme: bearer + description: Bearer authentication with API key in Authorization header diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b4a9b6c4..82cdd17a 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -194,6 +194,7 @@ Below is the complete mapping of which endpoints each permission category contro - [Show Machines](/api-reference/machines/show-machines) - [Show Reports](/api-reference/machines/show-reports) +- [SLA Backtest](/api-reference/host/sla-backtest) ### machine\_write diff --git a/docs.json b/docs.json index 485ba062..9082fe96 100644 --- a/docs.json +++ b/docs.json @@ -617,6 +617,8 @@ "icon": "lightbulb", "pages": [ "host/hosting-overview", + "host/sla-offers", + "host/sla-backtester", "host/understanding-verification", "host/earning" ] diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index f14faa29..51b75b98 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -125,7 +125,7 @@ The reserved discount pricing is determined by the hosts. If you intend to encou ![](/images/hosting-overview.webp) -Once that filter is selected, hosts who offer that discount will become easily visible. Hover over the rental button to see the discount rates that are offered. The original vs. the updated price will be shown as denoted by a stikethrough in the original amount: +Once that filter is selected, hosts who offer that discount will become easily visible. Hover over the rental button to see the discount rates that are offered. The original vs. the updated price will be shown as denoted by a strikethrough in the original amount: ![](/images/hosting-overview-2.webp) @@ -269,7 +269,7 @@ You can use the [uninstall script](https://s3.amazonaws.com/vast.ai/uninstall) ### What is this red error message on my machine? -If the hosting software detects and error, that error message will be listed on your machine in the machines page. Once the cause of the error has been resolved, most error messages will be automatically cleared after 1-2 hours. The quickest way to learn more about resolving specific error messages is to check out the hosting channels in [our discord](https://discord.gg/hSuEbSQ4X8). +If the hosting software detects an error, that error message will be listed on your machine in the machines page. Once the cause of the error has been resolved, most error messages will be automatically cleared after 1-2 hours. The quickest way to learn more about resolving specific error messages is to check out the hosting channels in [our discord](https://discord.gg/hSuEbSQ4X8). ### Why is my machine not listed? diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 916e136b..7713aee2 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -6,7 +6,7 @@ description: "Replay your machine's historical earnings through SLA math to prev The **SLA earnings backtester** lets you answer a practical question before you list: *if I had offered SLA at reliability **R** with confidence **P**, how would that have affected my earnings on this machine over the last few months?* -It replays your machine's **real historical compute earnings and uptime** through the same v5 SLA math used in production settlement, then compares the simulated result to what you actually earned from SLA (if anything). +It replays your machine's **real historical compute earnings and uptime** through the same SLA settlement math used in production, then compares the simulated result to what you actually earned from SLA (if anything). The backtester is available through the API only. You must own the machine and use an API key with **`machine_read`** permission. @@ -17,16 +17,16 @@ The backtester is available through the API only. You must own the machine and u Use the backtester before you enable SLA on a listing, or when you want to tune parameters: - **Pick a reliability target** — see how often you would have kept premiums vs paid out -- **Compare confidence levels** — tighter confidence means higher premiums for clients but more risk to you if uptime slips +- **Compare confidence levels** — tighter confidence means lower premiums for clients but more risk to you if uptime slips - **Stress-test bad weeks** — use the optional flat uptime override to see payout size if reliability dropped -- **Compare to history** — each day includes `historical_sla`, your machine's realized SLA earnings in that period (zero if you were not offering SLA) +- **Compare to history** — each day includes `historical_sla`, your machine's realized SLA earnings on that day (zero if you were not offering SLA) For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). ## How it works 1. You choose a machine, date range, reliability target (`r`), and confidence (`p`). -2. The API loads per-day earnings from your machine's history (`machine_earns`). +2. The API loads per-day earnings from your machine's rental history. 3. For each active day, it computes GPU, storage, and bandwidth earnings plus simulated SLA host earnings. 4. It returns a day-by-day breakdown and summary totals. @@ -40,7 +40,11 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). GET /api/v0/host/sla_backtest/ ``` -Requires Bearer authentication. Rate limited like other host API endpoints. +Requires Bearer authentication. This endpoint is rate-limited like other host API endpoints — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) for retry guidance. + + +Find your API key under **Account → API Keys** (requires [`machine_read`](/api-reference/permissions) permission). Your machine ID appears on the [Host Machines page](https://cloud.vast.ai/host/machines) or via [`vastai show machines`](/host/cli/show-machines). + ### Query parameters @@ -48,7 +52,7 @@ Requires Bearer authentication. Rate limited like other host API endpoints. | --- | --- | --- | | `machine_id` | Yes | ID of your machine | | `r` | Yes | Reliability target to simulate (0–1). Used as both target and claim. Example: `0.95` = 95%. | -| `p` | No | Host confidence (0–1). Maps to the same spread used when listing with `sla_sigma_x`. Default: ~0.67 (normal confidence). | +| `p` | No | Host confidence (0–1). Maps to the same spread used when listing with `sla_sigma_x` — see [Confidence values](#confidence-values-p) below. Default: `0.6667` (normal confidence, ≈ 67%). | | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | | `reliability` | No | Optional flat uptime override (0–1) for all replayed days. Ignores historical uptime — useful for what-if analysis ("what if every day had 90% uptime?"). | @@ -60,6 +64,7 @@ Requires Bearer authentication. Rate limited like other host API endpoints. | Default lookback | 90 days | | Maximum range | 366 days (inclusive) | | Ownership | Must own the machine | +| Rate limits | Per-endpoint; see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) | ### Example request @@ -135,7 +140,8 @@ A successful response looks like this (fields abbreviated): | Field | Meaning | | --- | --- | -| `has_data` | `true` if at least one day in the range had earnings to replay | +| `has_data` | `true` if at least one day in the range had earnings to replay. When `false`, `daily_results` is empty and summary totals are zero. | +| `start_day`, `end_day` | UTC day indices (days since January 1, 1970). Same encoding as `daily_results[].day`. Multiply by 86400 for a Unix timestamp. | | `covered_days` | Days with rental activity replayed through SLA math | | `skipped_days` | Days in the range with no activity (zero-filled in `daily_results`) | | `reliability` | Actual uptime ratio over the range (`total uptime / total active time`) | @@ -202,7 +208,8 @@ Higher confidence (higher `p`) → tighter spread → lower premiums for clients | --- | --- | --- | | 400 | `invalid_range` | `start_date` is after `end_date` | | 400 | `range_too_large` | More than 366 days requested | -| 400 | `invalid_params` | Invalid `r`, `p`, or other SLA parameter | +| 400 | `bad_request` | Invalid or out-of-range `r`, `p`, or other query parameter | +| 400 | `invalid_params` | Valid parameters but SLA math could not run (for example, insufficient history) | | 403 | `not_owner` | Machine belongs to another host | | 404 | `machine_not_found` | Invalid `machine_id` | @@ -217,5 +224,5 @@ Higher confidence (higher `p`) → tighter spread → lower premiums for clients ## Related documentation - [SLA Offers](/host/sla-offers) — listing parameters, economics, and risk scenarios -- [SLA Coverage (clients)](/guides/instances/choosing/sla-coverage) — how clients search and pay for SLA +- [SLA Backtest API](/api-reference/host/sla-backtest) — formal API reference for this endpoint - [API permissions](/api-reference/permissions) — `machine_read` scope required diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 89090e27..86a6c544 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -9,7 +9,7 @@ Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listi This page explains how SLA offers work from the host side — what you are promising, how pricing is calculated, and what happens when uptime is good or bad. -SLA settlement uses the **v5 asymmetric insurance model**. Premiums and payouts are settled daily based on measured uptime. +SLA settlement uses an **asymmetric insurance model**: when uptime is good you keep the premium, but when uptime is bad client payouts can exceed the premium you collected that day. Premiums and payouts are settled daily based on measured uptime. ## How it works (plain English) @@ -31,7 +31,7 @@ Under honest pricing, a host who delivers what they claim should roughly break e ## SLA parameters -When you list or update a machine, you can set these fields on the offer (via the host console or the [list machine API](/api-reference/machines/list-machine)): +When you list or update a machine, you can set these fields on the offer (via the host console, the [list machine CLI](/host/cli/list-machine), or `PUT /api/v0/machines/create_asks/`): | Parameter | API field | What it means | | --- | --- | --- | @@ -47,14 +47,14 @@ If you prefer thinking in confidence rather than `sla_sigma_x`, these presets ma | --- | --- | --- | --- | | High | ~83% | `0.2` | Lowest premiums — you are very sure about your claim | | Normal (default) | ~67% | `0.5` | Balanced default | -| Wide | 50% | `1.0` | Higher premiums — more uncertainty priced in | +| Wide | ~50% | `1.0` | Higher premiums — more uncertainty priced in | ### Validation rules Offers with invalid combinations are rejected at listing time: -- Reliability target and claim must be between 0 and 1 (exclusive of 0 for target). -- **Target cannot exceed claim** — you cannot promise coverage above what you claim you can deliver. +- The reliability target must be greater than 0 and at most 1. +- The reliability claim must be between 0 and 1 and must be **≥** the target. - Confidence spread must be positive and at most `3.0`. ## Listing an SLA offer @@ -65,7 +65,7 @@ When listing a machine in the [host machines page](https://cloud.vast.ai/host/ma ### CLI and API -Pass SLA fields to `vastai list machine` or `PUT /api/v0/machines/create_asks/`: +Pass SLA fields to `vastai list machine` or `PUT /api/v0/machines/create_asks/` (this endpoint creates or updates the listing for your machine): ```bash vastai list machine 12345 \ @@ -75,7 +75,7 @@ vastai list machine 12345 \ --sla_sigma_x 0.5 ``` -Minimal example (claim and confidence use defaults): +Minimal example (claim and confidence use defaults). Body for `PUT /api/v0/machines/create_asks/`: ```json { @@ -88,7 +88,7 @@ Minimal example (claim and confidence use defaults): This creates an offer with target `0.95`, claim `0.95`, and confidence spread `0.5`. -Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. +Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. ## Economics walkthrough @@ -100,7 +100,7 @@ Partial updates are supported when editing an existing listing. If you change on | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr) | | SLA premium to client | ~**$0.008/hr** (~$0.20/day) | -This premium is what a client searching for 95% reliability would see added to `dph_total`. +This premium is what a client searching for 95% reliability would see added to `dph_total` (dollars per hour, total rental price). ### If you meet your claim @@ -113,14 +113,14 @@ You keep most or all of the premium. ### If you miss the target -Settlement uses a **blend of recent and historical uptime** (not just a single day's raw percentage), but the direction is the same — worse uptime means larger client payouts: +These scenarios show settlement when uptime **drops to or below** the target — they are boundary illustrations, not typical good-uptime days. Settlement uses a **blend of recent and historical uptime** (not just a single day's raw percentage), but the direction is the same — worse uptime means larger client payouts: | Measured uptime (simplified) | Client net (per day) | You net (per day) | | --- | --- | --- | | At target (~95%) | ~+$42 | ~−$42 | | Well below target (~90% or less) | ~+$84 (full compute refund) | ~−$84 | -On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged twice for downtime they already did not pay for. +On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged twice for downtime they already did not pay for. Your maximum SLA loss on a single day is capped at that day's compute revenue. These examples use simplified single-day uptime for illustration. Production settlement aggregates uptime across multiple time windows (from about 1 day to about 3 years of history), so one bad hour does not always produce the maximum payout, and one good day does not instantly erase a long streak of problems. @@ -146,7 +146,7 @@ Clients pay more because you admit greater uncertainty. Use this if your uptime ### Scheduled maintenance -Maintenance windows that were scheduled with sufficient notice may be credited back toward uptime, reducing SLA penalties for planned downtime. Unplanned outages count fully. +Maintenance windows scheduled through [`vastai schedule maint`](/host/cli/schedule-maint) with sufficient advance notice may be credited back toward uptime, reducing SLA penalties for planned downtime. Unplanned outages count fully. ## Preview earnings before listing @@ -157,11 +157,11 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) to replay your machine's - **Set claim above target.** A claim of 99% with a target of 95% produces a much lower premium than matching them both at 95%. - **Tighten confidence only when earned.** Use high confidence (`sla_sigma_x ≈ 0.2`) after you have a strong uptime track record on that machine. - **Keep the machine online during active contracts.** SLA payouts and verification are separate systems, but both respond to downtime. +- **SLA applies to on-demand listings.** [Interruptible](/guides/instances/rental-types) instances use a separate bidding model and are not covered by SLA. - **Use the [SLA backtester](/host/sla-backtester)** to preview how different targets and confidence levels would have affected past earnings. ## Related documentation - [SLA Earnings Backtester](/host/sla-backtester) — preview SLA economics on historical earnings -- [SLA Coverage for Clients](/guides/instances/choosing/sla-coverage) — how clients search, compare, and benefit from SLA offers - [Hosting Overview](/host/hosting-overview) — offers, rental contracts, and listing basics - [Understanding Verification](/host/understanding-verification) — platform verification (separate from SLA, but related to trust) diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 4a066b81..8887e2f4 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -61,7 +61,7 @@ vastai list machine ID [options] - Client reliability coverage target (0–1). Values above 0 enable SLA on the offer. Legacy alias: `--sla_reliability`. (alias: `--sla-r-target`) + Client reliability coverage target (0–1). Values above 0 enable SLA on the offer. Set to `0` to disable SLA. Legacy alias: `--sla_reliability`. (alias: `--sla-r-target`) @@ -69,7 +69,7 @@ vastai list machine ID [options] - Host belief spread in log-failure space (0–3]. Lower = tighter confidence and lower client premiums. Defaults to `0.5`. (alias: `--sla-sigma-x`) + Host confidence spread — how wide your belief is around the claim. Must be greater than 0 and at most 3.0. Lower = tighter confidence and lower client premiums. Defaults to `0.5`. (alias: `--sla-sigma-x`) ## Description diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 4ef27387..12bf7112 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -63,7 +63,7 @@ VastAI.list_machine( - Host confidence spread (0–3]. Lower = tighter confidence. + Host confidence spread — how wide your belief is around the claim. Must be greater than 0 and at most 3.0. Lower = tighter confidence. ## Returns @@ -79,3 +79,16 @@ client = VastAI(api_key="YOUR_API_KEY") result = client.list_machine(id=12345) print(result) ``` + +With SLA enabled: + +```python +result = client.list_machine( + id=12345, + price_gpu=3.50, + sla_r_target=0.95, + sla_r_claim=0.99, + sla_sigma_x=0.5, +) +print(result) +``` From 12d00cf87ca22ece95da0be1d7215f98efd1c8d5 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:12:35 -0700 Subject: [PATCH 003/250] docs(sla): address doc-review consensus (cycle 1) Align create_asks error codes with production, add OpenAPI earnings fleet-scope note, choose-your-path routing, and merge duplicate FAQs. Co-authored-by: Cursor --- api-reference/openapi.yaml | 186 +++++++++-- api-reference/openapi/yaml/list_machine.yaml | 76 ++++- api-reference/openapi/yaml/show_earnings.yaml | 11 + api-reference/openapi/yaml/sla_backtest.yaml | 82 ++++- api-reference/permissions.mdx | 2 +- host/hosting-overview.mdx | 38 +-- host/sla-backtester.mdx | 140 ++++++-- host/sla-offers.mdx | 302 ++++++++++++++++-- snippets/host/cli/list-machine.mdx | 24 +- snippets/host/sdk/list-machine.mdx | 52 +-- 10 files changed, 738 insertions(+), 175 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index fd677de1..875b2e55 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4553,14 +4553,20 @@ paths: sla_r_target: type: number format: float - description: "Client reliability coverage target (0\u20131). Values\ - \ above 0 enable SLA on the offer.\nLegacy alias: sla_reliability.\n" + minimum: 0 + maximum: 0.9999 + description: "Client reliability coverage target. Values above 0 enable\ + \ SLA on the offer.\nMust be greater than 0 and at most 0.9999\ + \ when enabling SLA; exactly 1.0 is rejected.\nSet to 0 to disable\ + \ SLA. Legacy alias: sla_reliability.\n" sla_r_claim: type: number format: float - description: "Host reliability claim (0\u20131). Must be greater\ - \ than or equal to sla_r_target.\nDefaults to sla_r_target if\ - \ omitted.\n" + minimum: 0 + maximum: 0.9999 + description: "Host reliability claim. Must be greater than 0, at\ + \ most 0.9999, and greater than or equal to sla_r_target.\nDefaults\ + \ to sla_r_target if omitted.\n" sla_sigma_x: type: number format: float @@ -4581,15 +4587,42 @@ paths: properties: success: type: boolean - extended: - type: integer - description: Number of client contracts extended to new end date - msg: - type: string - description: Status message if success is false + you_sent: + type: object + description: Echo of the request body + results: + type: array + items: + type: object + properties: + machine_id: + type: integer + user_id: + type: integer + extended: + type: integer + description: Number of rental contracts extended + new_contracts: + type: array + items: + type: integer + description: IDs of newly created contracts + upd_contracts: + type: array + items: + type: integer + description: IDs of updated contracts example: success: true - extended: 2 + you_sent: + machine: 12345 + sla_r_target: 0.95 + results: + - machine_id: 12345 + user_id: 67890 + extended: 1 + new_contracts: [] + upd_contracts: [1] '400': description: Bad Request content: @@ -4599,10 +4632,25 @@ paths: properties: error: type: string - example: invalid_args + enum: + - invalid_args + - invalid_sla_params + example: invalid_sla_params + msg: + type: string + example: No such machine(s) for your account + '401': + description: Unauthorized + content: + application/json: + schema: + type: object + properties: + error: + type: string msg: type: string - example: Invalid machine id or parameters + example: Missing or invalid API key '403': description: Forbidden content: @@ -4612,10 +4660,13 @@ paths: properties: error: type: string + enum: + - not_authorized + - machine_locked example: not_authorized msg: type: string - example: Only machine owner can create ask contracts + example: API key lacks machine_write permission tags: - Machines operationId: listMachine @@ -7760,11 +7811,12 @@ paths: /api/v0/users/{user_id}/machine-earnings: get: summary: show earnings - description: 'Retrieves the earnings history for a specified time range and - optionally per machine. + description: | + Retrieves the earnings history for a specified time range and optionally per machine. + **Fleet scope:** `per_day[]` (including `sla_earn`) is always fleet-wide for the authenticated host, even when `machid` is set. For machine-scoped SLA totals, use `per_machine[].sla_earn` and `summary.total_sla`. - CLI Usage: `vastai show earnings [options]`' + CLI Usage: `vastai show earnings [options]` security: - BearerAuth: [] parameters: @@ -7813,6 +7865,9 @@ paths: type: number total_bwd: type: number + total_sla: + type: number + description: Net SLA earnings over the requested window. username: type: string email: @@ -7857,6 +7912,9 @@ paths: type: number bwd_earn: type: number + sla_earn: + type: number + description: Net SLA earnings for this machine over the window. per_day: type: array items: @@ -7872,6 +7930,9 @@ paths: type: number bwd_earn: type: number + sla_earn: + type: number + description: Net host SLA settlement for the UTC day. Positive when the host keeps premium income; negative when the host pays the client. '400': description: Bad Request - Invalid input syntax content: @@ -9014,6 +9075,7 @@ paths: /api/v0/host/sla_backtest: get: summary: sla backtest + operationId: slaBacktest description: 'Replays a machine''s historical compute earnings and uptime through SLA settlement math @@ -9039,9 +9101,9 @@ paths: format: float minimum: 0 exclusiveMinimum: true - maximum: 1 - description: "Reliability target to simulate (0\u20131). Used as both target\ - \ and claim." + maximum: 0.9999 + description: Reliability target to simulate (greater than 0 and at most 0.9999). + Used as both target and claim. Exactly 1.0 is rejected. - name: p in: query schema: @@ -9049,10 +9111,11 @@ paths: format: float minimum: 0 exclusiveMinimum: true + exclusiveMaximum: true maximum: 1 default: 0.6667 - description: "Host confidence (0\u20131). Maps to sla_sigma_x when listing.\ - \ Default 0.6667 (normal)." + description: Host confidence (greater than 0 and less than 1). Maps to sla_sigma_x + when listing. Default 0.6667 (normal). - name: start_date in: query schema: @@ -9070,8 +9133,18 @@ paths: type: number format: float minimum: 0 + exclusiveMinimum: true maximum: 1 - description: "Optional flat uptime override (0\u20131) for all replayed days." + description: Optional flat uptime override (greater than 0 and at most 1) for + all replayed days. Exactly 0 is rejected. + - name: beta + in: query + schema: + type: number + format: float + default: 0.5 + description: Backtest-only timescale weighting. Default 0.5 when omitted. Not + used in live settlement. Contact support before changing. responses: '200': description: Successful response @@ -9103,14 +9176,79 @@ paths: fleet_reliability: type: number format: float + description: Average reliability across your machines (including + this one). Context only. params: type: object + properties: + r: + type: number + format: float + p: + type: number + format: float + sigma_x: + type: number + format: float + reliability: + type: number + format: float + nullable: true + beta: + type: number + format: float daily_results: type: array items: type: object + properties: + day: + type: integer + gpu: + type: number + format: float + storage: + type: number + format: float + bandwidth: + type: number + format: float + uptime: + type: number + format: float + sla: + type: number + format: float + historical_sla: + type: number + format: float summary: type: object + properties: + total_gpu: + type: number + format: float + total_storage: + type: number + format: float + total_bandwidth: + type: number + format: float + total_sla: + type: number + format: float + total_earnings: + type: number + format: float + total_historical_sla: + type: number + format: float + worst_day_loss: + type: number + format: float + reserve: + type: number + format: float '400': description: Bad Request content: diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 5debd88f..b5ab49ed 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -64,14 +64,19 @@ paths: sla_r_target: type: number format: float + minimum: 0 + maximum: 0.9999 description: | - Client reliability coverage target (0–1). Values above 0 enable SLA on the offer. - Legacy alias: sla_reliability. + Client reliability coverage target. Values above 0 enable SLA on the offer. + Must be greater than 0 and at most 0.9999 when enabling SLA; exactly 1.0 is rejected. + Set to 0 to disable SLA. Legacy alias: sla_reliability. sla_r_claim: type: number format: float + minimum: 0 + maximum: 0.9999 description: | - Host reliability claim (0–1). Must be greater than or equal to sla_r_target. + Host reliability claim. Must be greater than 0, at most 0.9999, and greater than or equal to sla_r_target. Defaults to sla_r_target if omitted. sla_sigma_x: type: number @@ -93,15 +98,42 @@ paths: properties: success: type: boolean - extended: - type: integer - description: Number of client contracts extended to new end date - msg: - type: string - description: Status message if success is false + you_sent: + type: object + description: Echo of the request body + results: + type: array + items: + type: object + properties: + machine_id: + type: integer + user_id: + type: integer + extended: + type: integer + description: Number of rental contracts extended + new_contracts: + type: array + items: + type: integer + description: IDs of newly created contracts + upd_contracts: + type: array + items: + type: integer + description: IDs of updated contracts example: success: true - extended: 2 + you_sent: + machine: 12345 + sla_r_target: 0.95 + results: + - machine_id: 12345 + user_id: 67890 + extended: 1 + new_contracts: [] + upd_contracts: [1] '400': description: Bad Request content: @@ -111,10 +143,25 @@ paths: properties: error: type: string - example: invalid_args + enum: + - invalid_args + - invalid_sla_params + example: invalid_sla_params + msg: + type: string + example: No such machine(s) for your account + '401': + description: Unauthorized + content: + application/json: + schema: + type: object + properties: + error: + type: string msg: type: string - example: Invalid machine id or parameters + example: Missing or invalid API key '403': description: Forbidden content: @@ -124,10 +171,13 @@ paths: properties: error: type: string + enum: + - not_authorized + - machine_locked example: not_authorized msg: type: string - example: Only machine owner can create ask contracts + example: API key lacks machine_write permission tags: - Machines components: diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 97183ba3..62580d78 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -14,6 +14,8 @@ paths: description: | Retrieves the earnings history for a specified time range and optionally per machine. + **Note:** `per_day[]` aggregates SLA earnings across your entire fleet for each UTC day, even when `machid` is set. For machine-scoped SLA totals, use `per_machine[].sla_earn` or `summary.total_sla`. + CLI Usage: `vastai show earnings [options]` security: - BearerAuth: [] @@ -63,6 +65,9 @@ paths: type: number total_bwd: type: number + total_sla: + type: number + description: Net SLA earnings over the requested window. username: type: string email: @@ -107,6 +112,9 @@ paths: type: number bwd_earn: type: number + sla_earn: + type: number + description: Net SLA earnings for this machine over the window. per_day: type: array items: @@ -122,6 +130,9 @@ paths: type: number bwd_earn: type: number + sla_earn: + type: number + description: Net host SLA settlement for the UTC day. Positive when the host keeps premium income; negative when the host pays the client. '400': description: Bad Request - Invalid input syntax content: diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index 37a6e7a1..f782b825 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -10,6 +10,7 @@ paths: /api/v0/host/sla_backtest/: get: summary: sla backtest + operationId: slaBacktest description: | Replays a machine's historical compute earnings and uptime through SLA settlement math to preview premiums and payouts before listing with SLA. @@ -32,8 +33,8 @@ paths: format: float minimum: 0 exclusiveMinimum: true - maximum: 1 - description: Reliability target to simulate (0–1). Used as both target and claim. + maximum: 0.9999 + description: Reliability target to simulate (greater than 0 and at most 0.9999). Used as both target and claim. Exactly 1.0 is rejected. - name: p in: query schema: @@ -41,9 +42,10 @@ paths: format: float minimum: 0 exclusiveMinimum: true + exclusiveMaximum: true maximum: 1 default: 0.6667 - description: Host confidence (0–1). Maps to sla_sigma_x when listing. Default 0.6667 (normal). + description: Host confidence (greater than 0 and less than 1). Maps to sla_sigma_x when listing. Default 0.6667 (normal). - name: start_date in: query schema: @@ -60,8 +62,16 @@ paths: type: number format: float minimum: 0 + exclusiveMinimum: true maximum: 1 - description: Optional flat uptime override (0–1) for all replayed days. + description: Optional flat uptime override (greater than 0 and at most 1) for all replayed days. Exactly 0 is rejected. + - name: beta + in: query + schema: + type: number + format: float + default: 0.5 + description: Backtest-only timescale weighting. Default 0.5 when omitted. Not used in live settlement. Contact support before changing. responses: '200': description: Successful response @@ -93,14 +103,78 @@ paths: fleet_reliability: type: number format: float + description: Average reliability across your machines (including this one). Context only. params: type: object + properties: + r: + type: number + format: float + p: + type: number + format: float + sigma_x: + type: number + format: float + reliability: + type: number + format: float + nullable: true + beta: + type: number + format: float daily_results: type: array items: type: object + properties: + day: + type: integer + gpu: + type: number + format: float + storage: + type: number + format: float + bandwidth: + type: number + format: float + uptime: + type: number + format: float + sla: + type: number + format: float + historical_sla: + type: number + format: float summary: type: object + properties: + total_gpu: + type: number + format: float + total_storage: + type: number + format: float + total_bandwidth: + type: number + format: float + total_sla: + type: number + format: float + total_earnings: + type: number + format: float + total_historical_sla: + type: number + format: float + worst_day_loss: + type: number + format: float + reserve: + type: number + format: float '400': description: Bad Request content: diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 82cdd17a..cb08e0b6 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -194,7 +194,7 @@ Below is the complete mapping of which endpoints each permission category contro - [Show Machines](/api-reference/machines/show-machines) - [Show Reports](/api-reference/machines/show-reports) -- [SLA Backtest](/api-reference/host/sla-backtest) +- [SLA Backtest](/api-reference/host/sla-backtest) — API-only (hosts): replay historical earnings through SLA math. Requires `machine_read`. See [SLA Backtester](/host/sla-backtester). Console hosts should use **Set Pricing → SLA** preview instead. ### machine\_write diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 51b75b98..000d472a 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -38,16 +38,16 @@ Clients have high expectations coming from AWS or GCP. As a host, plan to offer ## Offers and Rental Contracts -Hosts can create offers (sometimes called listings) through the CLI command list machine or the machine control panel GUI on the host machines page. +Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). The main offer parameters include: -- the pricing for GPUs,internet,storage +- the pricing for GPUs, internet, storage - the discount schedule param which determines the price difference between [on-demand](/guides/instances/rental-types) and [reserved](/guides/instances/rental-types) instances - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) - the offer end date, which determines how long the offer accepts new rental contracts -- optional [SLA (reliability guarantee)](/host/sla-offers) parameters — reliability target, claim, and confidence +- **SLA (optional):** A reliability guarantee that clients can pay a premium for. Configure via **Set Pricing → SLA** in the console or the REST API — SLA parameters are not yet available in the published CLI/SDK. See [SLA Offers](/host/sla-offers) for parameters and field names. The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. @@ -59,7 +59,7 @@ Once clients rent your machine, it is very important to honor the terms of each ## The Rental Contract -By listing your machine, you create an offer visible to potential clients. A rental contract is created each time a client accepts your offer by renting an instance. The rental contract locks in all of the offer's terms at the time of rental, including pricing, the rental end date, and hardware specs, and those terms cannot be changed afterward. Each rental contract is independent, you may have multiple active rental contracts from different clients on the same machine, each with its own rental end date and pricing. +By listing your machine, you create an offer visible to potential clients. A rental contract is created each time a client accepts your offer by renting an instance. The rental contract locks in all of the offer's terms at the time of rental, including pricing, the rental end date, and hardware specs, and those terms cannot be changed afterward. Each rental contract is independent. You may have multiple active rental contracts from different clients on the same machine, each with its own rental end date and pricing. SLA terms lock at rent time — see [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). As the host, you are _committing_ to provide the services as advertised in your offer: @@ -107,7 +107,7 @@ You now have two active rental contracts on the same machine at different prices ### Min GPU -When clicking on the set pricing button, there is a min GPU field. The min GPU field allows you to set the smallest grouping of GPU rentals available on your machine in powers of 2, or down to 1. For example, if you have an 8X 3090 and set min gpu to 2, clients can create instances with 2, 4, or 8 GPUs. If you set min gpus to 1, then clients can make instances with 1, 2, 4 or 8 GPUs. +When clicking on the set pricing button, there is a min GPU field. The min GPU field allows you to set the smallest grouping of GPU rentals available on your machine in powers of 2, or down to 1. For example, if you have an 8X 3090 and set min GPU to 2, clients can create instances with 2, 4, or 8 GPUs. If you set min GPU to 1, then clients can make instances with 1, 2, 4 or 8 GPUs. ### On-demand Price @@ -129,7 +129,7 @@ Once that filter is selected, hosts who offer that discount will become easily v ![](/images/hosting-overview-2.webp) -This discount is not static, but rather scales over time that the user rents the machine for. These values are determined by the individual host(s). +This discount is not static, but rather scales with the length of time the user rents the machine. These values are determined by individual hosts. As a host, you can set this number yourself to 0 if you wish to opt out of this feature. @@ -195,7 +195,7 @@ If you have raised the pricing, you cannot extend the current rental contracts. ## Testing your own machine -It is vital to test your own machine to ensure the ports and software is running smoothly. +It is vital to test your own machine to ensure the ports and software are running smoothly. ### Setup a separate client account @@ -235,7 +235,9 @@ Unlisting the offer will prevent new rental contracts from being created, but do Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored, you cannot take the machine offline until every active rental contract has ended. -For unplanned or unscheduled maintenance, use the CLI and the schedule maint command. That will notify the client that you **have** to take the machine down and that they should save their work. You can specify a date and duration. +For unplanned or unscheduled maintenance, use the CLI and the [`vastai schedule maint`](/host/cli/schedule-maint) command. That will notify the client that you **have** to take the machine down and that they should save their work. You can specify a date and duration. + +For SLA-listed machines, scheduled downtime may still count against your reliability target. Uptime credit for maintenance is evaluated case by case and is not guaranteed — give at least 24 hours' notice before extended work. When you schedule maintenance, clients may be notified via [Host Notifications](/host/notifications) (including `maintenance_scheduled` webhooks). See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ## Uninstalling @@ -251,9 +253,15 @@ Hosting on Vast will require some Linux knowledge, as you will be maintaining a You can create an invoice by going to the "Billing" page, and then click the box for "Include Charges" under "Generate Billing History". -### How do I check if my machine is listed? +### Why can't I find my machine in search? + +If your machine seems unlisted or missing from console search: -If your machine seems unlisted, try this command `vastai search offers 'machine_id=MACHINE_ID verified=any'` to see if the CLI finds it. If there is a result, your machine is properly listed +- **CLI check:** `vastai search offers 'machine_id=MACHINE_ID verified=any'` — if this returns a result, your machine is listed. +- **Console search:** There are 10,000+ listings; search shows a small subset. You usually cannot find one specific machine through normal browsing — this is expected. +- **Ranking check:** Use narrow filters to see similar machines, e.g. `vastai search offers 'gpu_name=RTX_4090 cpu_ram>257 cpu_ram<258'`. + +See also [Why is my machine not listed?](#why-is-my-machine-not-listed) below. ### How does verification work? @@ -273,7 +281,7 @@ If the hosting software detects an error, that error message will be listed on y ### Why is my machine not listed? -You won't be able to see it on the GUI right away, but you can search using the [CLI](/guides/instances/managing-instances). +You won't be able to see it on the GUI right away, but you can search using the [CLI](/guides/instances/managing-instances). See [Why can't I find my machine in search?](#why-cant-i-find-my-machine-in-search) above for the full checklist. ### Can I send a message to a client using my machine letting them know that I fixed an issue that they were having? @@ -306,11 +314,3 @@ Prior images are cached. ### My storage for clients is somehow full. I just have a few jobs stored in my server and most of them are old and didn't delete once the job finished. A lot of them are really old, can I remove them to free up some space? We suggest that you try cleaning up the docker build cache, as it sometimes frees up far more space than it claims. You can also clean up old unused images. - -### I can't find my machine? - -If your machine seems unlisted, try this command `vastai search offers 'machine_id=MACHINE_ID verified=any'` to see if the CLI finds it. If there is a result, your machine is properly listed. - -### Why can't I see my machine on the Search page in the console? - -There are over 10,000+ listings on Vast, and search only displays a small subset. You will usually not be able to find any one specific machine through most normal searches. This is expected and intentional behavior of our system. You can use `vastai search offers 'machine_id=MACHINE_ID verified=any'`, to see your machine's listing. If you want to get an understanding of the machines ranking above yours you can use very narrow filters to see what similar machines are ranking above you. For example, something like: `vastai search offers 'gpu_name=RTX_4090 cpu_ram>257 cpu_ram<258'` is a decently constrained search that will most likely include a given machine you are looking for (that fits these filters) amongst others that are similar. Keep in mind our Auto Sort that `search offers` defaults to is comprised of both ranking various factors as well as an element of randomness. \ No newline at end of file diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 7713aee2..1dfeb644 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -4,19 +4,27 @@ description: "Replay your machine's historical earnings through SLA math to prev "canonical": "/host/sla-backtester" --- -The **SLA earnings backtester** lets you answer a practical question before you list: *if I had offered SLA at reliability **R** with confidence **P**, how would that have affected my earnings on this machine over the last few months?* +The **SLA earnings backtester** lets you answer a practical question before you list: *if I had offered SLA at reliability target **`r`** and confidence level **`p`**, how would that have affected my earnings on this machine over the last few months?* (**`r`** = reliability target; **`p`** = host confidence — both defined in [Query parameters](#query-parameters) below.) It replays your machine's **real historical compute earnings and uptime** through the same SLA settlement math used in production, then compares the simulated result to what you actually earned from SLA (if anything). -The backtester is available through the API only. You must own the machine and use an API key with **`machine_read`** permission. +**Don't want to use the API?** The backtester is optional. Use the web console SLA preview and the economics walkthrough on [SLA Offers](/host/sla-offers#listing-an-sla-offer) to evaluate SLA before listing. The backtester is for hosts who want historical replay via the API. +## Choose your path + +| If you want to… | Use | +| --- | --- | +| Preview SLA before your first listing | Web console (**Set Pricing → SLA** on the machine page) — no API key needed | +| Simulate historical earnings for one machine | This page's single-machine `curl` example | +| Review many machines at once | [Fleet workflow](#fleet-workflow) below (advanced; Linux/macOS + `jq`) | + ## When to use it -Use the backtester before you enable SLA on a listing, or when you want to tune parameters: +Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. If `has_data` is `false`, widen the date range or pick a machine with more activity: -- **Pick a reliability target** — see how often you would have kept premiums vs paid out +- **Pick a reliability target** — see how often you would have kept premiums or paid them out on historical data - **Compare confidence levels** — tighter confidence means lower premiums for clients but more risk to you if uptime slips - **Stress-test bad weeks** — use the optional flat uptime override to see payout size if reliability dropped - **Compare to history** — each day includes `historical_sla`, your machine's realized SLA earnings on that day (zero if you were not offering SLA) @@ -30,12 +38,33 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 3. For each active day, it computes GPU, storage, and bandwidth earnings plus simulated SLA host earnings. 4. It returns a day-by-day breakdown and summary totals. -**Simulated vs listing parameters.** In the backtester, reliability target and claim are both set to **`r`**. When you actually list a machine, you can set **`sla_r_claim` above `sla_r_target`** for lower client premiums. The backtester is conservative: it shows the economics when target and claim match. +**Simulated vs listing parameters.** In the backtester, reliability target and claim are both set to **`r`**. When you actually list a machine, you can set **`sla_r_claim` above `sla_r_target`** for lower client premiums. + +**Active vs idle days.** **Idle days** are days with no rental earnings on the machine (no active compute rental). These days typically produce no SLA premium or payout in the simulation. Days with no rental activity appear in the results as zero-filled rows but do not count toward `covered_days`. Only days with actual earnings are replayed through SLA math. + + +**Simulation vs live listing** +- The backtester sets claim equal to target and may show higher premiums than live listing or the console preview. +- For client-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console. +- For tail risk, trust `worst_day_loss`, not headline `total_sla`. +- The backtester defaults `beta` to `0.5` when omitted. Live SLA settlement does **not** use this default — weighting is fixed when you list. Treat `total_sla` as a tail-risk estimate, not an exact live preview. + + +## Before you start -**Active vs idle days.** Days with no rental activity (zero compute delta) appear in the results as zero-filled rows but do not count toward `covered_days`. Only days with actual earnings are replayed through SLA math. +**Prerequisites:** API key with `machine_read` permission, machine ID from the [Host Machines page](https://cloud.vast.ai/host/machines), and `curl` (or Postman). On Windows, use WSL or Postman. This is the same numeric machine ID as `machid` on the earnings API and `machine` in listing requests. + +1. Open **Account → API Keys** in the console and create a key with **`machine_read`** enabled. +2. Copy the token and use `Authorization: Bearer YOUR_API_KEY` in the examples below. See [Create API Key](/api-reference/accounts/create-api-key) and [Authentication](/api-reference/authentication). +3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). The machine must have at least a few weeks of rental activity — new or idle machines should use the console **Set Pricing → SLA** preview instead (the backtester returns `has_data: false` without sufficient history). +4. Run the baseline `curl` below (default date range — no custom dates required) and check `has_data` in the response. ## API reference + +The backtester is available through the REST API only. You must own the machine and use an API key with **`machine_read`** permission. Python SDK (`vastai` package) support is not yet available — use the `curl` examples below. + + ``` GET /api/v0/host/sla_backtest/ ``` @@ -43,7 +72,7 @@ GET /api/v0/host/sla_backtest/ Requires Bearer authentication. This endpoint is rate-limited like other host API endpoints — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) for retry guidance. -Find your API key under **Account → API Keys** (requires [`machine_read`](/api-reference/permissions) permission). Your machine ID appears on the [Host Machines page](https://cloud.vast.ai/host/machines) or via [`vastai show machines`](/host/cli/show-machines). +Find your API key under **Account → API Keys** (requires [`machine_read`](/api-reference/permissions) permission). See [Create API Key](/api-reference/accounts/create-api-key) if you need a new key. Your machine ID appears on the [Host Machines page](https://cloud.vast.ai/host/machines) or via [`vastai show machines`](/host/cli/show-machines). ### Query parameters @@ -51,11 +80,12 @@ Find your API key under **Account → API Keys** (requires [`machine_read`](/api | Parameter | Required | Description | | --- | --- | --- | | `machine_id` | Yes | ID of your machine | -| `r` | Yes | Reliability target to simulate (0–1). Used as both target and claim. Example: `0.95` = 95%. | -| `p` | No | Host confidence (0–1). Maps to the same spread used when listing with `sla_sigma_x` — see [Confidence values](#confidence-values-p) below. Default: `0.6667` (normal confidence, ≈ 67%). | +| `r` | Yes | Reliability target to simulate (greater than 0 and at most **0.9999**). Used as both target and claim. Example: `0.95` = 95%. Exactly `1.0` is rejected. | +| `p` | No | Host confidence (greater than 0 and **less than 1** — not equal to 1). Maps to the same spread used when listing with `sla_sigma_x` — see [Confidence values](#confidence-values-p) below. Default: `0.6667` (normal confidence, ≈ 67%). | | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | -| `reliability` | No | Optional flat uptime override (0–1) for all replayed days. Ignores historical uptime — useful for what-if analysis ("what if every day had 90% uptime?"). | +| `reliability` | No | Optional flat uptime override (greater than 0 and at most 1). Ignores historical uptime — useful for what-if analysis. Use `0.01` to approximate near-total downtime; `0` is rejected with `400 bad_request`. | +| `beta` | No | Backtest-only timescale weighting. Default `0.5` when omitted. **Not used in live settlement.** Contact support before changing. | ### Limits @@ -68,17 +98,29 @@ Find your API key under **Account → API Keys** (requires [`machine_read`](/api ### Example request +Minimal baseline (default 90-day lookback — no custom dates required): + +```bash +curl -s -H "Authorization: Bearer YOUR_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667" +``` + +Custom date range (optional — Jan–Apr 2024 for illustration): + ```bash +# start_date = Jan 1, 2024; end_date = Apr 1, 2024 +# Tip: on Linux, `date -d '2024-01-01' +%s`; on macOS, `date -j -f '%Y-%m-%d' '2024-01-01' +%s` +# On Windows, use WSL or an online epoch converter. curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.67&start_date=1704067200&end_date=1711929600" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667&start_date=1704067200&end_date=1711929600" ``` Compare two confidence levels on the same history: ```bash -# Normal confidence (~67%) +# Normal confidence (~67%, default 0.6667) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.67" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667" # High confidence (~83%) — tighter spread, lower simulated premiums curl -s -H "Authorization: Bearer YOUR_API_KEY" \ @@ -89,11 +131,13 @@ Stress-test with flat 90% uptime: ```bash curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.67&reliability=0.90" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667&reliability=0.90" ``` ## Reading the response +**If you only read three fields:** Check `has_data` (widen dates if `false`), then `summary.worst_day_loss`, then `summary.total_sla`. + A successful response looks like this (fields abbreviated): ```json @@ -111,7 +155,8 @@ A successful response looks like this (fields abbreviated): "r": 0.95, "p": 0.6667, "sigma_x": 0.5, - "reliability": null + "reliability": null, + "beta": 0.5 }, "daily_results": [ { @@ -131,7 +176,8 @@ A successful response looks like this (fields abbreviated): "total_sla": 8.1, "total_earnings": 3900.6, "total_historical_sla": 0.0, - "worst_day_loss": 42.0 + "worst_day_loss": 42.0, + "reserve": 0.0 } } ``` @@ -140,12 +186,12 @@ A successful response looks like this (fields abbreviated): | Field | Meaning | | --- | --- | -| `has_data` | `true` if at least one day in the range had earnings to replay. When `false`, `daily_results` is empty and summary totals are zero. | -| `start_day`, `end_day` | UTC day indices (days since January 1, 1970). Same encoding as `daily_results[].day`. Multiply by 86400 for a Unix timestamp. | +| `has_data` | `true` if at least one day in the range had earnings to replay. When `false`, there was no billable rental activity in the range: `covered_days` is `0`, `skipped_days` equals the number of days in the requested window, `daily_results` contains one zero-filled row per day in the window (not an empty array), summary totals are `0.0`, and top-level `reliability` is `null`. Try a wider window or a machine with more rental history. | +| `start_day`, `end_day` | UTC day indices (days since January 1, 1970). Same encoding as `daily_results[].day`. Multiply by 86400 for a Unix timestamp. For example, day `19723` × 86400 = `1704067200` = January 1, 2024 UTC. Most hosts can ignore these and use `start_date`/`end_date` in requests. | | `covered_days` | Days with rental activity replayed through SLA math | | `skipped_days` | Days in the range with no activity (zero-filled in `daily_results`) | | `reliability` | Actual uptime ratio over the range (`total uptime / total active time`) | -| `fleet_reliability` | Average reliability across your other machines (context only) | +| `fleet_reliability` | Average reliability across your machines (including this one). Context only; may be uninformative if you operate a single machine. | ### Per-day fields (`daily_results`) @@ -167,12 +213,13 @@ Plot `sla` over time to see which days would have helped or hurt under the chose | `total_earnings` | Compute + simulated SLA | | `total_historical_sla` | Sum of realized historical SLA in the range | | `worst_day_loss` | Largest single-day client payout (your worst simulated loss) | +| `reserve` | Reserved for future use — ignore in production decisions today. | ## Interpreting results ### Mostly positive `sla` values -Your historical uptime was strong relative to the target. SLA would likely have been a net positive — small premiums on good days, few payout days. +Your historical uptime was strong relative to the target. SLA would likely have been a net positive — small premiums on good days, few days with payouts. ### Negative `sla` on specific days @@ -188,16 +235,20 @@ Under the simulated parameters, SLA would have cost you money over this window. ### Using `reliability` override -Setting `reliability=0.90` while keeping `r=0.99` answers: *if every active day had 90% uptime, how bad would SLA payouts get?* Use this to understand tail risk before committing to a high target. +Setting `reliability=0.90` while keeping `r=0.99` answers: *if every active day had 90% uptime, how bad would SLA payouts get?* Use this to understand worst-case payout exposure before committing to a high target. ## Confidence values (`p`) -The backtester accepts **`p`** (confidence) instead of `sla_sigma_x`. They map to the same presets used when listing: + +**`p` and `sla_sigma_x` use different scales** — do not copy numeric values between them. For example, `p=0.5` (Wide confidence) maps to `sla_sigma_x ≈ 1.0`, not `0.5`. Use the table below to translate between the two. + + +The backtester accepts **`p`** (confidence) instead of `sla_sigma_x`. The mappings below match the presets used when listing: | Confidence `p` | Approx. label | Listing equivalent | | --- | --- | --- | | `0.83` | High | `sla_sigma_x ≈ 0.2` | -| `0.67` | Normal (default) | `sla_sigma_x ≈ 0.5` | +| `0.6667` | Normal (default) | `sla_sigma_x ≈ 0.5` | | `0.50` | Wide | `sla_sigma_x ≈ 1.0` | Higher confidence (higher `p`) → tighter spread → lower premiums for clients, but less room for uptime to slip before payouts. @@ -206,23 +257,56 @@ Higher confidence (higher `p`) → tighter spread → lower premiums for clients | HTTP | `error` | Cause | | --- | --- | --- | +| 401 | — | Missing or invalid Bearer token — see [Authentication](/api-reference/authentication) | | 400 | `invalid_range` | `start_date` is after `end_date` | | 400 | `range_too_large` | More than 366 days requested | -| 400 | `bad_request` | Invalid or out-of-range `r`, `p`, or other query parameter | -| 400 | `invalid_params` | Valid parameters but SLA math could not run (for example, insufficient history) | +| 400 | `bad_request` | Schema, bounds, or unknown-parameter failures (for example, `r` or `p` out of range) | +| 400 | `invalid_params` | Inputs pass validation but fail inside settlement simulation | | 403 | `not_owner` | Machine belongs to another host | | 404 | `machine_not_found` | Invalid `machine_id` | +| 429 | *(rate limited)* | Too many requests — retry with backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | ## Recommended workflow -1. **Run a baseline backtest** on a machine with at least a few weeks of rental history. Use your intended target and normal confidence (`p=0.67`). +1. **Run a baseline backtest** on a machine with at least a few weeks of rental history: + - Check your machine's uptime history on the [Host Machines page](https://cloud.vast.ai/host/machines), then use the console SLA preview or backtester — do not rely on the dashboard reliability score alone (see [Machine reliability score vs SLA uptime](/host/sla-offers#machine-reliability-score-vs-sla-uptime)). + - Choose a target at or slightly below your current reliability for your first backtest. + - Use normal confidence (`p=0.6667`). + - If `has_data` is `false`, widen the date range or wait for more rental history. 2. **Check `worst_day_loss`** — can you absorb that payout from a bad day? 3. **Try a higher target** (for example `r=0.99`) and see how `total_sla` changes. 4. **Run a stress test** with `reliability=0.90` at your intended target. -5. **List with headroom** — set `sla_r_claim` above `sla_r_target` on the actual offer for better client pricing than the backtester shows (see [SLA Offers](/host/sla-offers)). +5. **List with headroom** — set `sla_r_claim` above `sla_r_target` on the actual offer for better client pricing than the backtester shows (the backtester uses target = claim; see [SLA Offers](/host/sla-offers)). + +## Fleet workflow + +For hosts automating fleet review. Console-only hosts can run the baseline `curl` once per machine instead. + +1. List machine IDs: `vastai show machines -q` (numeric IDs only) or `vastai show machines --raw | jq -r '.machines[].id'`. +2. Run backtests **sequentially** (one machine at a time) with a short sleep on `429` responses: + +```bash +for id in $(vastai show machines -q); do + curl -s -H "Authorization: Bearer $VAST_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=0.95&p=0.6667" \ + | jq '{machine_id: '"$id"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' + sleep 1 +done +``` + +Use a `machine_read` key scoped to the machines you own. On `429`, back off per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Parallel requests are not recommended unless you implement backoff. + +3. Compare `worst_day_loss` and `total_sla` across machines. +4. Apply `sla_r_claim` headroom when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). + +## When stuck + +- **`has_data: false`** — Widen the date range or wait for rental history. +- **`401`** — Check API key permissions (`machine_read`) and Bearer header format. +- **Still stuck** — Ask in the [host Discord](https://discord.gg/hSuEbSQ4X8). ## Related documentation -- [SLA Offers](/host/sla-offers) — listing parameters, economics, and risk scenarios - [SLA Backtest API](/api-reference/host/sla-backtest) — formal API reference for this endpoint +- [SLA Offers](/host/sla-offers) — listing parameters, economics, and risk scenarios - [API permissions](/api-reference/permissions) — `machine_read` scope required diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 86a6c544..ff504280 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -8,40 +8,82 @@ Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listi This page explains how SLA offers work from the host side — what you are promising, how pricing is calculated, and what happens when uptime is good or bad. - -SLA settlement uses an **asymmetric insurance model**: when uptime is good you keep the premium, but when uptime is bad client payouts can exceed the premium you collected that day. Premiums and payouts are settled daily based on measured uptime. + +SLA settlement is **lopsided by design**: when uptime is good, you keep the premium, but when uptime is bad, client payouts can exceed the premium you collected that day. Premiums and payouts are settled daily based on measured uptime. Optional: preview SLA economics before listing — use the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). The console preview works on first-time listings. + + + +When a client rents a machine with SLA enabled, they pay a small premium on top of the normal hourly rate. If uptime falls below the promised target, credits are applied to their account automatically. SLA applies to on-demand rentals only — not [interruptible](/guides/instances/rental-types) instances. +## Choose your path + +| Goal | Start here | +| --- | --- | +| Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer) | +| Enable or update SLA via API | [Before you enable SLA](#before-you-enable-sla) → [API (for automation)](#api-for-automation) | +| Monitor payouts after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | + +## Before you enable SLA + +Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machine appears on **Host → Machines** with no red error status. + +SLA can be enabled on a first-time listing, but you still need base listing fields (GPU price, offer end date, etc.). See [Listing an SLA offer](#listing-an-sla-offer) and [Offer End Date](/host/hosting-overview#offer-end-date). + + +**Rental types:** SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. If a client attempts to reserve or prepay an SLA-enabled offer, the request is rejected. + + +- Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. +- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview and the economics walkthrough below. Wait for rental history before trusting `worst_day_loss`. Consider wider confidence or lower targets until you have a few weeks of data. + ## How it works (plain English) Think of an SLA offer as three linked ideas: 1. **Reliability target** — the uptime level the listing is priced around (for example, 95% or 99%). 2. **Your reliability claim** — what you believe your machine will actually deliver. -3. **Your confidence** — how sure you are about that claim. A tight confidence means you stand behind a narrow range; a wide confidence means you admit more uncertainty and clients pay a higher premium. +3. **Your confidence** — how sure you are about that claim. Tight confidence means you stand behind a narrow range; wide confidence means a wider defensible range and clients pay a higher premium. When a client rents with SLA enabled: - They pay **compute** (GPU, storage, bandwidth) plus a **daily SLA premium**. - Each day, Vast measures how long the instance was online and settles the SLA. - **Good uptime** → you keep the premium for that day. -- **Bad uptime** → you pay the client from your earnings (up to the day's compute charges plus premium). +- **Bad uptime** → you pay the client from your earnings (up to the day's compute revenue). -Under honest pricing, a host who delivers what they claim should roughly break even on SLA over time — premiums balance payouts. +Under honest pricing, a host who delivers what they claim should roughly break even on SLA over time — premiums and payouts balance. ## SLA parameters -When you list or update a machine, you can set these fields on the offer (via the host console, the [list machine CLI](/host/cli/list-machine), or `PUT /api/v0/machines/create_asks/`): +When you list or update a machine, set SLA fields via the host console or `PUT /api/v0/machines/create_asks/` (see [Listing an SLA offer](#listing-an-sla-offer) below). -| Parameter | API field | What it means | -| --- | --- | --- | -| Reliability target | `sla_r_target` | The coverage level baked into the offer. Set above `0` to enable SLA. Values are fractions between 0 and 1 (for example, `0.95` = 95%). Legacy alias: `sla_reliability`. | -| Reliability claim | `sla_r_claim` | Your advertised belief about machine uptime. Defaults to the reliability target if omitted. Must be **≥** the target. | -| Confidence spread | `sla_sigma_x` | How wide your belief is around the claim. Lower = more confident (cheaper for clients). Defaults to `0.5` if omitted. | +| Parameter | API field | Backtester alias | What it means | +| --- | --- | --- | --- | +| Reliability target | `sla_r_target` | `r` | The uptime level the offer is priced around. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.95` = 95%). Exactly `1.0` is rejected. Legacy alias: `sla_reliability` (deprecated; use `sla_r_target` instead). Avoid sending both. | +| Reliability claim | `sla_r_claim` | — (backtester sets claim = target) | Your advertised belief about machine uptime. Defaults to the reliability target if omitted. Must be **≥** the target. Same bounds as target (greater than 0, at most 0.9999). | +| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the claim. Lower = more confident (cheaper for clients). Defaults to `0.5` if omitted. | + + +| Concept | Console | Listing API | Backtester | Client sees | +| --- | --- | --- | --- | --- | +| Reliability target | Target | `sla_r_target` | `r` | Target % (coverage level) | +| Reliability claim | Claim | `sla_r_claim` | (set equal to target in backtester) | — | +| Confidence | Confidence | `sla_sigma_x` | `p` (different scale — do not copy directly) | — | +| All-in hourly price | — | — | — | `dph_total` in search | + +**Confidence is not an uptime target.** It controls how aggressively premiums are priced around your claim. + + +### Machine reliability score vs SLA uptime + +The **reliability score** on the Host Machines page reflects connection and instance-start behavior (and is earnings-weighted). **SLA settlement** measures whether covered instances met your published uptime target for billing purposes. + +Do not assume the dashboard score equals SLA uptime. Use **Set Pricing → SLA** in the console or the backtester on historical data to choose `sla_r_target`, `sla_r_claim`, and confidence — not the Machines-page number alone. ### Confidence presets -If you prefer thinking in confidence rather than `sla_sigma_x`, these presets match the shipped defaults: +If you prefer to think in terms of confidence rather than `sla_sigma_x`, these presets match the shipped defaults. A confidence of ~83% means you believe there is roughly an 83% chance your machine's actual uptime will meet or exceed your claim — higher confidence means lower client premiums. | Label | Approx. confidence | `sla_sigma_x` | Effect on premium | | --- | --- | --- | --- | @@ -53,44 +95,141 @@ If you prefer thinking in confidence rather than `sla_sigma_x`, these presets ma Offers with invalid combinations are rejected at listing time: -- The reliability target must be greater than 0 and at most 1. -- The reliability claim must be between 0 and 1 and must be **≥** the target. +- The reliability target must be greater than 0 and at most **0.9999** when enabling SLA. Set to `0` to disable SLA. +- The reliability claim must be greater than 0, at most **0.9999**, and must be **≥** the target. - Confidence spread must be positive and at most `3.0`. + +If listing is rejected with `error: "invalid_sla_params"`, check the `msg` field against the rules above. Common causes: claim below target, `sla_sigma_x` out of range, values of exactly `1.0`, or invalid partial-update combinations. + + +### SLA and GPU slicing + +SLA settlement applies per rental contract. If your machine has multiple GPU slices rented by different clients (GPU slicing — see **Min GPU** in [Hosting Overview](/host/hosting-overview)), each contract's SLA is settled independently based on the uptime experienced by that instance. + +The backtester replays **machine-level** daily earnings (total compute across all active rentals on that machine). `worst_day_loss` in `summary` reflects the worst simulated day for the whole machine in the replay window — not a single GPU slice in isolation. + +On sliced machines, a full-machine outage can affect every concurrent SLA rental at once. Use `worst_day_loss` as your primary tail-risk metric for the machine, and sanity-check exposure against how many SLA-covered instances you typically run in parallel. Do **not** multiply `worst_day_loss` by contract count — the backtester already models machine-level compute for the replay window. + +To see how many rentals are active on a machine, check the [Host Machines page](https://cloud.vast.ai/host/machines) or run `vastai show machines` and inspect the rented/active instance fields for that `machine_id`. + +### SLA on extended contracts + +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. + +Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. + ## Listing an SLA offer ### Web console -When listing a machine in the [host machines page](https://cloud.vast.ai/host/machines), enable SLA and set your reliability target, claim, and confidence. The console shows how these affect the premium clients will see. +1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. +2. Expand **SLA**. +3. Set **Reliability target** (`sla_r_target`), **Reliability claim** (`sla_r_claim`), and **Confidence** (`sla_sigma_x` or a preset). +4. Save and confirm the SLA premium preview before listing. + +#### Web console SLA preview + +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA premium and payout exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. -### CLI and API +### API (for automation) -Pass SLA fields to `vastai list machine` or `PUT /api/v0/machines/create_asks/` (this endpoint creates or updates the listing for your machine): +New hosts: use the web console steps above first. Use the API when you need scripting, partial updates, or fleet automation. + + +SLA listing via `vastai list machine` and `VastAI.list_machine()` is **not yet available** in the published CLI/SDK. Use the REST API below until tooling support is released. + + +#### Before you start + +SLA listing requires the REST API today — CLI and SDK SLA flags are not yet available in published tooling. + +1. Open **Account → API Keys** and create a key. See [Create API Key](/api-reference/accounts/create-api-key). +2. For listing SLA offers, enable **`machine_write`**. For backtesting first, add **`machine_read`**. For post-listing earnings, add **`billing_read`** (one key can include multiple permissions). +3. Use the key as `Authorization: Bearer YOUR_API_KEY` in the `curl` examples below. See [Authentication](/api-reference/authentication). +4. To enable SLA today, use `PUT /api/v0/machines/create_asks/` or **Set Pricing → SLA** in the console. `vastai list machine` hits the same endpoint for non-SLA fields only until CLI SLA flags ship. The listing body field is `machine` (same ID as backtester `machine_id` and earnings `machid`). +5. For the full request/response schema (including `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, and `invalid_sla_params`), see [List Machine](/api-reference/machines/list-machine). + +Listing or updating SLA parameters requires an API key with **`machine_write`** permission. Backtesting requires **`machine_read`**. See [API permissions](/api-reference/permissions). ```bash -vastai list machine 12345 \ - --price_gpu 3.50 \ - --sla_r_target 0.95 \ - --sla_r_claim 0.99 \ - --sla_sigma_x 0.5 +curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "machine": 12345, + "price_gpu": 3.50, + "sla_r_target": 0.95, + "sla_r_claim": 0.99, + "sla_sigma_x": 0.5, + "end_date": 1735689600 + }' ``` -Minimal example (claim and confidence use defaults). Body for `PUT /api/v0/machines/create_asks/`: +Set `end_date` so the offer does not stay open indefinitely — especially important for SLA commitments. See [Offer End Date](/host/hosting-overview#offer-end-date). + +Minimal example (claim and confidence use defaults): ```json { "machine": 12345, "price_gpu": 3.50, + "end_date": 1735689600, "sla_r_target": 0.95 } ``` +Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric payout risk. See [Offer End Date](/host/hosting-overview#offer-end-date). + This creates an offer with target `0.95`, claim `0.95`, and confidence spread `0.5`. Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. +**SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: + +```bash +curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"machine": 12345, "sla_r_target": 0.99, "sla_r_claim": 0.995, "sla_sigma_x": 2.0}' +``` + +**Disable SLA on new rentals** — set `sla_r_target` to `0` (active contracts keep their terms). + +#### Common errors + +| Status | Code | When it happens | +| --- | --- | --- | +| 401 | — | Missing or invalid Bearer token | +| 403 | `not_authorized` | API key lacks `machine_write` or other required permission | +| 400 | `invalid_args` | Machine ID not found for your account (includes other hosts' machines) | +| 400 | `invalid_sla_params` | SLA parameters failed validation | +| 400 | `invalid_args` | Malformed or incompatible request body | +| 403 | `machine_locked` | Machine is decommissioned or migration-locked | + +**Success response (200):** + +```json +{ + "success": true, + "you_sent": { "...": "echo of your request body" }, + "results": [ + { + "machine_id": 12345, + "user_id": 67890, + "extended": 1, + "new_contracts": [], + "upd_contracts": [1] + } + ] +} +``` + +- `extended` — integer count of rental contracts extended (read from `results[0]`, not the top level) +- `new_contracts` / `upd_contracts` — arrays of contract IDs + ## Economics walkthrough **Setup:** You list an H100 at **$3.50/hr** GPU price with target **95%**, claim **99%**, and normal confidence (`sla_sigma_x = 0.5`). @@ -100,30 +239,48 @@ Partial updates are supported when editing an existing listing. If you change on | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr) | | SLA premium to client | ~**$0.008/hr** (~$0.20/day) | -This premium is what a client searching for 95% reliability would see added to `dph_total` (dollars per hour, total rental price). +Premium sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst-case payout exposure (`worst_day_loss`), not exact client premiums. For client-visible SLA pricing, use the console **Set Pricing → SLA** preview or inspect `dph_total` in search results. + + +The economics above assume claim (99%) is above target (95%). The [backtester](/host/sla-backtester) is conservative — it sets claim equal to target — so its simulated payouts will differ. Use `worst_day_loss` from the backtester as your tail-risk reference, then adjust expectations when you list with headroom (claim above target). Use the web console SLA preview for the exact premium clients will see in search (`dph_total`). + + +This premium is what a client searching for 95% reliability would see added to the total hourly price in search results (`dph_total` — visible in [Search Offers](/api-reference/search/search-offers) results). ### If you meet your claim -| Measured uptime (simplified) | Client net (per day) | You net (per day) | +| Measured uptime (simplified) | Client SLA cost (per day) | You net (per day) | | --- | --- | --- | | ~100% (excellent day) | −$0.20 (paid premium) | +$0.20 (keep premium) | | ~99% (good day) | −$0.17 | +$0.17 | +Negative client SLA cost = premium paid by the client. Positive = payout received by the client. + You keep most or all of the premium. ### If you miss the target + +Payouts scale relative to the day's compute revenue, not the premium collected. A single bad day at your target boundary can cost as much as 200+ days of collected premiums. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. + + + +Visible client premiums are lower than backtester output when `sla_r_claim` is above `sla_r_target`. Use `worst_day_loss` as your primary tail-risk reference. The table below illustrates payout at the target boundary only. + + These scenarios show settlement when uptime **drops to or below** the target — they are boundary illustrations, not typical good-uptime days. Settlement uses a **blend of recent and historical uptime** (not just a single day's raw percentage), but the direction is the same — worse uptime means larger client payouts: -| Measured uptime (simplified) | Client net (per day) | You net (per day) | +| Measured uptime (simplified) | Client SLA cost (per day) | You net (per day) | | --- | --- | --- | | At target (~95%) | ~+$42 | ~−$42 | | Well below target (~90% or less) | ~+$84 (full compute refund) | ~−$84 | -On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged twice for downtime they already did not pay for. Your maximum SLA loss on a single day is capped at that day's compute revenue. +To put the asymmetry in perspective: at ~$0.20/day in premiums, it takes roughly 210 good days to accumulate the $42 you could lose on a single day at the target boundary. The premium is a small fraction of daily compute, while the payout scales against total daily compute revenue. + +On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged a premium on top of compute charges for periods when the instance was down. Your maximum SLA loss on any single settlement day is capped at that day's compute revenue, regardless of how the multi-window aggregation evaluates uptime. -These examples use simplified single-day uptime for illustration. Production settlement aggregates uptime across multiple time windows (from about 1 day to about 3 years of history), so one bad hour does not always produce the maximum payout, and one good day does not instantly erase a long streak of problems. +Production settlement blends recent and historical uptime — not a single raw day — so short outages may not produce the maximum illustrated payout. ## Risk scenarios @@ -146,19 +303,100 @@ Clients pay more because you admit greater uncertainty. Use this if your uptime ### Scheduled maintenance -Maintenance windows scheduled through [`vastai schedule maint`](/host/cli/schedule-maint) with sufficient advance notice may be credited back toward uptime, reducing SLA penalties for planned downtime. Unplanned outages count fully. +Maintenance windows scheduled through [`vastai schedule maint`](/host/cli/schedule-maint) may be credited back toward uptime, reducing SLA penalties for planned downtime. Unplanned outages count fully toward SLA settlement. + + +Planned maintenance credit is not guaranteed. The platform evaluates advance notice (generally at least 24 hours recommended) and maintenance duration when determining credit eligibility. **Treat any scheduled downtime as a potential SLA payout event when modeling risk.** Contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or email [contact@vast.ai](mailto:contact@vast.ai) before extended maintenance on an SLA-listed machine to confirm credit eligibility. + ## Preview earnings before listing -Use the [SLA Earnings Backtester](/host/sla-backtester) to replay your machine's historical earnings through SLA math and compare simulated premiums and payouts before you enable SLA on a listing. +Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `machine_read` API key) to replay historical earnings through SLA math. Console-only hosts can use the web console SLA preview and the economics walkthrough on this page instead. + +## When things go wrong + +- **Listing rejected (`invalid_sla_params`)** — Re-check target, claim, and `sla_sigma_x` against [validation rules](#validation-rules). +- **Unexpected payout** — Review uptime; re-run the backtester with a low `reliability` stress value (for example `0.01`). +- **Severe outage** — Disable SLA on new contracts (`sla_r_target=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. + +## Monitoring SLA after listing + +After you enable SLA, premiums and payouts settle on UTC (Coordinated Universal Time) day boundaries. + +### Console (recommended for day-to-day checks) + +1. Open **Host → Billing** (or **Earnings** / **Reports**). +2. Select the machine and the UTC day range you care about. +3. Look for SLA premium and payout line items alongside compute earnings. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. + +### CLI + +**Linux (GNU date):** + +```bash +vastai show earnings --machine_id --start_date $(date -d '7 days ago' +%F) --end_date $(date +%F) +``` + +**macOS:** + +```bash +vastai show earnings --machine_id --start_date $(date -v-7d +%F) --end_date $(date +%F) +``` + +On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. + +### API (automation) + + +**Console users:** Skip this section if you check payouts in **Host → Billing**. No API key is required. + + +**API keys for SLA** + +| Task | Permission | +| --- | --- | +| SLA backtester | `machine_read` | +| List or update SLA on an offer | `machine_write` | +| Post-listing SLA earnings | `billing_read` | + +For API automation only — console users can stop after the Console subsection above. + +`GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key (separate from `machine_read` used for the backtester). See [`show earnings`](/api-reference/billing/show-earnings). + + +When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. + +There is no per-machine daily SLA series in this API. For day-level reconciliation on one machine, use the console earnings report. + + +**Machine-scoped window total:** + +```bash +curl -s -H "Authorization: Bearer $VAST_API_KEY" \ + "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?machid=12345&last_days=7" \ + | jq '.per_machine[] | select(.machine_id==12345) | {machine_id, sla_earn}' +``` + +**Sign convention** (same as backtester `sla` / `historical_sla`): + +| Field | Good day (meet target) | Bad day (miss target) | +| --- | --- | --- | +| `per_machine[].sla_earn` / `summary.total_sla` | Positive (premium kept) | Negative (payout paid) | +| Fleet `per_day[].sla_earn` | Positive (premium kept) | Negative (payout paid) | + +- `{user_id}` — Your account ID (from **Account → Profile** in the console, or `vastai show user`). +- `sday` / `eday` — UTC day indices (days since 1970-01-01). Prefer `?last_days=N` on the API if you do not want to compute indices manually. +- Settlement is evaluated on UTC day boundaries. + +The backtester's `historical_sla` replays past settlement and is not a live billing feed. For fleet-scale day-level forensics per machine, use the console or poll `per_machine[].sla_earn` over rolling windows. ## Tips for competitive SLA offers - **Set claim above target.** A claim of 99% with a target of 95% produces a much lower premium than matching them both at 95%. - **Tighten confidence only when earned.** Use high confidence (`sla_sigma_x ≈ 0.2`) after you have a strong uptime track record on that machine. - **Keep the machine online during active contracts.** SLA payouts and verification are separate systems, but both respond to downtime. -- **SLA applies to on-demand listings.** [Interruptible](/guides/instances/rental-types) instances use a separate bidding model and are not covered by SLA. -- **Use the [SLA backtester](/host/sla-backtester)** to preview how different targets and confidence levels would have affected past earnings. +- **SLA applies to on-demand rentals only.** It does not apply to interruptible/bid instances or reserved/prepay rentals. If a client attempts to reserve or prepay an SLA-enabled offer, the request is rejected. When a client starts an on-demand rental on an SLA-enabled offer, SLA terms lock for that rental contract and do not change if you later edit the offer. +- **Use the [SLA backtester](/host/sla-backtester) (API-only)** to preview how different targets and confidence levels would have affected past earnings. ## Related documentation diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 8887e2f4..149e8971 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -1,7 +1,11 @@ -list a machine for rent +Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. + +SLA parameters (`--sla_r_target`, `--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. To enable SLA on a listing, use `PUT /api/v0/machines/create_asks/` — see [SLA Offers](/host/sla-offers#api-for-automation). + + ## Usage ```bash @@ -11,7 +15,7 @@ vastai list machine ID [options] ## Arguments - id of machine to list + ID of the machine to list. ## Options @@ -60,24 +64,12 @@ vastai list machine ID [options] Price for disk on volume contract offer. Defaults to price_disk. Invalid if vol_size is 0. (alias: `--vol_price`) - - Client reliability coverage target (0–1). Values above 0 enable SLA on the offer. Set to `0` to disable SLA. Legacy alias: `--sla_reliability`. (alias: `--sla-r-target`) - - - - Host reliability claim (0–1). Must be ≥ `sla_r_target`. Defaults to `sla_r_target` if omitted. (alias: `--sla-r-claim`) - - - - Host confidence spread — how wide your belief is around the claim. Must be greater than 0 and at most 3.0. Lower = tighter confidence and lower client premiums. Defaults to `0.5`. (alias: `--sla-sigma-x`) - - ## Description Performs the same action as pressing the "LIST" button on the site https://cloud.vast.ai/host/machines. -On the end date the listing will expire and your machine will unlist. However any existing client jobs will still remain until ended by their owners. +On the end date the listing will expire and your machine will unlist. However, any existing rental contracts will still remain until ended by their owners. Once you list your machine and it is rented, it is extremely important that you don't interfere with the machine in any way. -If your machine has an active client job and then goes offline, crashes, or has performance problems, this could permanently lower your reliability rating. +If your machine has an active rental contract and then goes offline, crashes, or has performance problems, this could permanently lower your reliability rating. We strongly recommend you test the machine first and only list when ready. ## Examples diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 12bf7112..ffeb2230 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -1,7 +1,11 @@ -List details of a single machine with optional pricing and configuration parameters. +Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. + +SLA parameters (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are **not yet available** in the published Python SDK. To enable SLA on a listing, use `PUT /api/v0/machines/create_asks/` — see [SLA Offers](/host/sla-offers#api-for-automation). + + ## Signature ```python @@ -14,56 +18,41 @@ VastAI.list_machine( discount_rate: Optional[float] = None, min_chunk: Optional[int] = None, end_date: Optional[str] = None, - sla_r_target: Optional[float] = None, - sla_r_claim: Optional[float] = None, - sla_sigma_x: Optional[float] = None, ) -> str ``` ## Parameters - id + Machine ID to list. - price_gpu + GPU rental price in $/hour for active instances. - price_disk + Storage price in $/GB/month for inactive instances. - price_inetu + Upload bandwidth price in $/GB. - price_inetd + Download bandwidth price in $/GB. - discount_rate + Max long-term prepay discount rate fraction (default 0.4). - min_chunk + Minimum GPUs that must be rented together (GPU slicing). - end_date - - - - Reliability coverage target (0–1). Values above 0 enable SLA. - - - - Host reliability claim (0–1). Must be ≥ sla_r_target. - - - - Host confidence spread — how wide your belief is around the claim. Must be greater than 0 and at most 3.0. Lower = tighter confidence. + Offer expiration (Unix timestamp or MM/DD/YYYY). ## Returns @@ -76,19 +65,6 @@ VastAI.list_machine( from vastai import VastAI client = VastAI(api_key="YOUR_API_KEY") -result = client.list_machine(id=12345) -print(result) -``` - -With SLA enabled: - -```python -result = client.list_machine( - id=12345, - price_gpu=3.50, - sla_r_target=0.95, - sla_r_claim=0.99, - sla_sigma_x=0.5, -) +result = client.list_machine(id=12345, price_gpu=3.50) print(result) ``` From 9eac9981055e76f58836f62836b42981155b6218 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:19:01 -0700 Subject: [PATCH 004/250] docs(sla): address doc-review consensus (cycle 2) Clarify economics sign convention, console LIST step, dph_total, OpenAPI SLA CLI caveat, fleet backtest error handling, and webhook subscription key. Co-authored-by: Cursor --- api-reference/openapi.yaml | 10 ++++-- api-reference/openapi/yaml/list_machine.yaml | 6 ++-- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 11 +++++-- host/sla-offers.mdx | 34 ++++++++++++++------ snippets/host/cli/list-machine.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 2 +- 7 files changed, 47 insertions(+), 20 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 875b2e55..cc2c35ef 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4499,11 +4499,17 @@ paths: description: 'Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. - Allows setting pricing, minimum GPU requirements, end date, discount rates, + Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. - CLI Usage: `vastai list machine [options]`' + SLA request-body fields (sla_r_target, sla_r_claim, sla_sigma_x) are + supported on this REST endpoint. The published CLI and SDK do not yet expose + them — use the host console (Set Pricing → SLA) or REST/curl until CLI/SDK + support ships. + + + CLI Usage (non-SLA fields): `vastai list machine [options]`' security: - BearerAuth: [] requestBody: diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index b5ab49ed..93d860b0 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -12,9 +12,11 @@ paths: summary: list machine description: | Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. - Allows setting pricing, minimum GPU requirements, end date, discount rates, and SLA parameters. + Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. - CLI Usage: `vastai list machine [options]` + SLA request-body fields (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are supported on this REST endpoint. The published CLI and SDK do not yet expose them — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. + + CLI Usage (non-SLA fields): `vastai list machine [options]` security: - BearerAuth: [] requestBody: diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 000d472a..47bbd094 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -237,7 +237,7 @@ Remember that a single machine may have multiple active rental contracts from di For unplanned or unscheduled maintenance, use the CLI and the [`vastai schedule maint`](/host/cli/schedule-maint) command. That will notify the client that you **have** to take the machine down and that they should save their work. You can specify a date and duration. -For SLA-listed machines, scheduled downtime may still count against your reliability target. Uptime credit for maintenance is evaluated case by case and is not guaranteed — give at least 24 hours' notice before extended work. When you schedule maintenance, clients may be notified via [Host Notifications](/host/notifications) (including `maintenance_scheduled` webhooks). See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). +For SLA-listed machines, scheduled downtime may still count against your reliability target. Uptime credit for maintenance is evaluated case by case and is not guaranteed — give at least 24 hours' notice before extended work. When you schedule maintenance, clients may be notified via [Host Notifications](/host/notifications) — subscribe to `host:maintenance_scheduled` (payloads use `notif_type: maintenance_scheduled`). See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ## Uninstalling diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 1dfeb644..993f2f2a 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -282,14 +282,19 @@ Higher confidence (higher `p`) → tighter spread → lower premiums for clients For hosts automating fleet review. Console-only hosts can run the baseline `curl` once per machine instead. +```bash +export VAST_API_KEY="YOUR_API_KEY" +``` + 1. List machine IDs: `vastai show machines -q` (numeric IDs only) or `vastai show machines --raw | jq -r '.machines[].id'`. -2. Run backtests **sequentially** (one machine at a time) with a short sleep on `429` responses: +2. Run backtests **sequentially** (one machine at a time): ```bash for id in $(vastai show machines -q); do - curl -s -H "Authorization: Bearer $VAST_API_KEY" \ + resp=$(curl -sf -H "Authorization: Bearer $VAST_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=0.95&p=0.6667" \ - | jq '{machine_id: '"$id"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' + || echo '{"error":"request_failed"}') + echo "$resp" | jq '{machine_id: '"$id"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data, error: .error}' sleep 1 done ``` diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index ff504280..41a917da 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -70,11 +70,15 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Reliability target | Target | `sla_r_target` | `r` | Target % (coverage level) | | Reliability claim | Claim | `sla_r_claim` | (set equal to target in backtester) | — | | Confidence | Confidence | `sla_sigma_x` | `p` (different scale — do not copy directly) | — | -| All-in hourly price | — | — | — | `dph_total` in search | +| All-in hourly price | — | — | — | `dph_total` (dollars per hour total in search — compute plus SLA premium when enabled) | **Confidence is not an uptime target.** It controls how aggressively premiums are priced around your claim. + +**Confidence in one sentence:** The **preset name** (High / Normal / Wide) controls how **tight your claim spread** is around your target, which changes **client premiums** (tighter → lower premiums, wider → higher premiums). In the console, use the labeled presets rather than raw numbers. The ~83% figure describes how often your machine's actual uptime is expected to meet or exceed your claim — not a separate setting. + + ### Machine reliability score vs SLA uptime The **reliability score** on the Host Machines page reflects connection and instance-start behavior (and is earnings-weighted). **SLA settlement** measures whether covered instances met your published uptime target for billing purposes. @@ -127,6 +131,7 @@ Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-cove 2. Expand **SLA**. 3. Set **Reliability target** (`sla_r_target`), **Reliability claim** (`sla_r_claim`), and **Confidence** (`sla_sigma_x` or a preset). 4. Save and confirm the SLA premium preview before listing. +5. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. #### Web console SLA preview @@ -144,6 +149,8 @@ SLA listing via `vastai list machine` and `VastAI.list_machine()` is **not yet a SLA listing requires the REST API today — CLI and SDK SLA flags are not yet available in published tooling. +Before you call this endpoint, your machine must appear on **Host → Machines** with the daemon connected. This call creates or updates the **offer**, not machine registration. See [Host setup](https://cloud.vast.ai/host/setup/). + 1. Open **Account → API Keys** and create a key. See [Create API Key](/api-reference/accounts/create-api-key). 2. For listing SLA offers, enable **`machine_write`**. For backtesting first, add **`machine_read`**. For post-listing earnings, add **`billing_read`** (one key can include multiple permissions). 3. Use the key as `Authorization: Bearer YOUR_API_KEY` in the `curl` examples below. See [Authentication](/api-reference/authentication). @@ -239,7 +246,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr) | | SLA premium to client | ~**$0.008/hr** (~$0.20/day) | -Premium sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst-case payout exposure (`worst_day_loss`), not exact client premiums. For client-visible SLA pricing, use the console **Set Pricing → SLA** preview or inspect `dph_total` in search results. +Premium sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst-case payout exposure (`worst_day_loss`), not exact client premiums. For client-visible SLA pricing, use the console **Set Pricing → SLA** preview or inspect **`dph_total`** (dollars per hour total in search — compute plus SLA premium when enabled). The economics above assume claim (99%) is above target (95%). The [backtester](/host/sla-backtester) is conservative — it sets claim equal to target — so its simulated payouts will differ. Use `worst_day_loss` from the backtester as your tail-risk reference, then adjust expectations when you list with headroom (claim above target). Use the web console SLA preview for the exact premium clients will see in search (`dph_total`). @@ -249,13 +256,13 @@ This premium is what a client searching for 95% reliability would see added to t ### If you meet your claim -| Measured uptime (simplified) | Client SLA cost (per day) | You net (per day) | +In the tables below, **Client pays / receives** uses negative values when the client pays you a premium (money you keep) and positive values when the client receives a payout. + +| Measured uptime (simplified) | Client pays / receives (per day) | You net (per day) | | --- | --- | --- | -| ~100% (excellent day) | −$0.20 (paid premium) | +$0.20 (keep premium) | +| ~100% (excellent day) | −$0.20 (premium paid to you) | +$0.20 (keep premium) | | ~99% (good day) | −$0.17 | +$0.17 | -Negative client SLA cost = premium paid by the client. Positive = payout received by the client. - You keep most or all of the premium. ### If you miss the target @@ -270,7 +277,7 @@ Visible client premiums are lower than backtester output when `sla_r_claim` is a These scenarios show settlement when uptime **drops to or below** the target — they are boundary illustrations, not typical good-uptime days. Settlement uses a **blend of recent and historical uptime** (not just a single day's raw percentage), but the direction is the same — worse uptime means larger client payouts: -| Measured uptime (simplified) | Client SLA cost (per day) | You net (per day) | +| Measured uptime (simplified) | Client pays / receives (per day) | You net (per day) | | --- | --- | --- | | At target (~95%) | ~+$42 | ~−$42 | | Well below target (~90% or less) | ~+$84 (full compute refund) | ~−$84 | @@ -325,9 +332,9 @@ After you enable SLA, premiums and payouts settle on UTC (Coordinated Universal ### Console (recommended for day-to-day checks) -1. Open **Host → Billing** (or **Earnings** / **Reports**). -2. Select the machine and the UTC day range you care about. -3. Look for SLA premium and payout line items alongside compute earnings. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. +1. Open **Host → Billing** (or **Earnings** / **Reports**) for the machine and UTC date range. +2. Look for rows labeled **SLA premium** (client payments you keep) and **SLA payout** (amounts you owe after a miss). Exact menu names may vary; filter by machine ID and date if needed. +3. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. ### CLI @@ -345,6 +352,13 @@ vastai show earnings --machine_id --start_date $(date -v-7d +%F) --end_date On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. +```bash +vastai show earnings --machine_id --start_date $(date -d '7 days ago' +%F) --end_date $(date +%F) --raw \ + | jq '.per_machine[] | {machine_id, sla_earn}' +``` + +Positive `sla_earn` = net SLA premium you kept that period; negative = net payout you owe. See the sign-convention table in the API subsection below. + ### API (automation) diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 149e8971..fb39f22c 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA parameters (`--sla_r_target`, `--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. To enable SLA on a listing, use `PUT /api/v0/machines/create_asks/` — see [SLA Offers](/host/sla-offers#api-for-automation). +SLA parameters (`--sla_r_target`, `--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). ## Usage diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index ffeb2230..306265f0 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA parameters (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are **not yet available** in the published Python SDK. To enable SLA on a listing, use `PUT /api/v0/machines/create_asks/` — see [SLA Offers](/host/sla-offers#api-for-automation). +SLA parameters (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are **not yet available** in the published Python SDK. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). ## Signature From e9b9e50dfe4affa048dbe70fa3977e9360807f0d Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:24:50 -0700 Subject: [PATCH 005/250] docs(sla): address doc-review consensus (cycle 3) Document console Save-then-LIST vs REST publish, host-centric economics tables, earnings rate limits, merge semantics, and maintenance webhooks. Co-authored-by: Cursor --- host/hosting-overview.mdx | 4 +-- host/sla-backtester.mdx | 10 ++++-- host/sla-offers.mdx | 51 ++++++++++++++++++++---------- snippets/host/cli/list-machine.mdx | 2 ++ snippets/host/sdk/list-machine.mdx | 2 ++ 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 47bbd094..44f5ba73 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -233,11 +233,11 @@ The proper way to perform maintenance on your machine is to wait until all activ Unlisting the offer will prevent new rental contracts from being created, but does not affect existing ones. However if you have active rental contracts, you could set the offer end date to match the latest rental end date, allowing new clients to rent instances that end at the same date. Once the end date is reached, you can then unlist the machine and then perform maintenance. -Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored, you cannot take the machine offline until every active rental contract has ended. +Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. You cannot take the machine offline until every active rental contract has ended. For unplanned or unscheduled maintenance, use the CLI and the [`vastai schedule maint`](/host/cli/schedule-maint) command. That will notify the client that you **have** to take the machine down and that they should save their work. You can specify a date and duration. -For SLA-listed machines, scheduled downtime may still count against your reliability target. Uptime credit for maintenance is evaluated case by case and is not guaranteed — give at least 24 hours' notice before extended work. When you schedule maintenance, clients may be notified via [Host Notifications](/host/notifications) — subscribe to `host:maintenance_scheduled` (payloads use `notif_type: maintenance_scheduled`). See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). +For SLA-listed machines, scheduled downtime may still count against your reliability target. Uptime credit for maintenance is evaluated case by case and is not guaranteed — give at least 24 hours' notice before extended work. When you schedule maintenance with `vastai schedule maint`, clients with active rentals may be notified automatically. If you want your own alerts (email, webhook, etc.), optionally subscribe via [Host Notifications](/host/notifications) — for example, to `host:maintenance_scheduled`. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ## Uninstalling diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 993f2f2a..dee0b7d8 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -38,7 +38,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 3. For each active day, it computes GPU, storage, and bandwidth earnings plus simulated SLA host earnings. 4. It returns a day-by-day breakdown and summary totals. -**Simulated vs listing parameters.** In the backtester, reliability target and claim are both set to **`r`**. When you actually list a machine, you can set **`sla_r_claim` above `sla_r_target`** for lower client premiums. +**Simulated vs listing parameters.** In the backtester, reliability target and claim are both set to **`r`** — the backtester cannot set `sla_r_claim` above `sla_r_target`. Claim-headroom simulation is console-only today. When you actually list a machine, you can set **`sla_r_claim` above `sla_r_target`** for lower client premiums. Workflow: backtest `worst_day_loss` at your target, then verify visible premiums in **Set Pricing → SLA** (or `dph_total` in search) before listing with claim above target. **Active vs idle days.** **Idle days** are days with no rental earnings on the machine (no active compute rental). These days typically produce no SLA premium or payout in the simulation. Days with no rental activity appear in the results as zero-filled rows but do not count toward `covered_days`. Only days with actual earnings are replayed through SLA math. @@ -280,7 +280,7 @@ Higher confidence (higher `p`) → tighter spread → lower premiums for clients ## Fleet workflow -For hosts automating fleet review. Console-only hosts can run the baseline `curl` once per machine instead. +This section is for hosts automating fleet review. Console-only hosts can run the baseline `curl` once per machine instead. ```bash export VAST_API_KEY="YOUR_API_KEY" @@ -294,7 +294,11 @@ for id in $(vastai show machines -q); do resp=$(curl -sf -H "Authorization: Bearer $VAST_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=0.95&p=0.6667" \ || echo '{"error":"request_failed"}') - echo "$resp" | jq '{machine_id: '"$id"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data, error: .error}' + if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then + echo "machine_id=$id error: $(echo "$resp" | jq -r '.error')" + else + echo "$resp" | jq '{machine_id: '"$id"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' + fi sleep 1 done ``` diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 41a917da..dec080af 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -9,7 +9,7 @@ Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listi This page explains how SLA offers work from the host side — what you are promising, how pricing is calculated, and what happens when uptime is good or bad. -SLA settlement is **lopsided by design**: when uptime is good, you keep the premium, but when uptime is bad, client payouts can exceed the premium you collected that day. Premiums and payouts are settled daily based on measured uptime. Optional: preview SLA economics before listing — use the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). The console preview works on first-time listings. +SLA settlement is **lopsided by design**: when uptime is good, you keep the premium, but when uptime is bad, client payouts can exceed the premium you collected that day. Premiums and payouts are settled daily based on measured uptime. You can optionally preview SLA economics before listing — use the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). The console preview works on first-time listings. @@ -28,6 +28,8 @@ When a client rents a machine with SLA enabled, they pay a small premium on top Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machine appears on **Host → Machines** with no red error status. +Before enabling SLA, finish normal listing setup: test your machine, set GPU price and offer end date, choose on-demand vs interruptible, and understand [Testing your own machine](/host/hosting-overview#testing-your-own-machine) and offer terms in [Hosting overview](/host/hosting-overview). + SLA can be enabled on a first-time listing, but you still need base listing fields (GPU price, offer end date, etc.). See [Listing an SLA offer](#listing-an-sla-offer) and [Offer End Date](/host/hosting-overview#offer-end-date). @@ -60,7 +62,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | -| Reliability target | `sla_r_target` | `r` | The uptime level the offer is priced around. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.95` = 95%). Exactly `1.0` is rejected. Legacy alias: `sla_reliability` (deprecated; use `sla_r_target` instead). Avoid sending both. | +| Reliability target | `sla_r_target` | `r` | The uptime level the offer is priced around. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.95` = 95%). Exactly `1.0` is rejected. Legacy alias: `sla_reliability` (deprecated; use `sla_r_target` instead). If both are sent, `sla_r_target` takes precedence. | | Reliability claim | `sla_r_claim` | — (backtester sets claim = target) | Your advertised belief about machine uptime. Defaults to the reliability target if omitted. Must be **≥** the target. Same bounds as target (greater than 0, at most 0.9999). | | Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the claim. Lower = more confident (cheaper for clients). Defaults to `0.5` if omitted. | @@ -133,6 +135,10 @@ Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-cove 4. Save and confirm the SLA premium preview before listing. 5. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. + +In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same as pressing **LIST** or running `vastai list machine`), not a save-only draft. + + #### Web console SLA preview In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA premium and payout exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. @@ -192,6 +198,8 @@ This creates an offer with target `0.95`, claim `0.95`, and confidence spread `0 Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. + +Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. For fleet automation, prefer read-modify-write: `vastai show machines` → merge → `PUT /api/v0/machines/create_asks/`. **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: @@ -246,22 +254,22 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr) | | SLA premium to client | ~**$0.008/hr** (~$0.20/day) | -Premium sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst-case payout exposure (`worst_day_loss`), not exact client premiums. For client-visible SLA pricing, use the console **Set Pricing → SLA** preview or inspect **`dph_total`** (dollars per hour total in search — compute plus SLA premium when enabled). +Premium sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst single-day payout exposure (`worst_day_loss`), not exact client premiums. For authoritative client-visible premiums, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers — not backtester `total_sla` when claim exceeds target. -The economics above assume claim (99%) is above target (95%). The [backtester](/host/sla-backtester) is conservative — it sets claim equal to target — so its simulated payouts will differ. Use `worst_day_loss` from the backtester as your tail-risk reference, then adjust expectations when you list with headroom (claim above target). Use the web console SLA preview for the exact premium clients will see in search (`dph_total`). +The economics above assume **claim above target** (headroom): claim (99%) is above target (95%), so clients see lower premiums than if both matched. The [backtester](/host/sla-backtester) cannot simulate claim headroom — it sets claim equal to target — so its simulated premiums will be higher. Use `worst_day_loss` from the backtester as your worst single-day payout reference, then verify visible premiums in **Set Pricing → SLA** (or `dph_total` in search) before listing with claim above target. -This premium is what a client searching for 95% reliability would see added to the total hourly price in search results (`dph_total` — visible in [Search Offers](/api-reference/search/search-offers) results). +This premium is what a client searching for 95% reliability would see added to the total hourly price in search results (`dph_total` — visible in the console SLA preview or [Search Offers](/api-reference/search/search-offers) results). ### If you meet your claim -In the tables below, **Client pays / receives** uses negative values when the client pays you a premium (money you keep) and positive values when the client receives a payout. +**You net** uses host earnings signs: positive = premium you kept; negative = payout you owed the client. -| Measured uptime (simplified) | Client pays / receives (per day) | You net (per day) | -| --- | --- | --- | -| ~100% (excellent day) | −$0.20 (premium paid to you) | +$0.20 (keep premium) | -| ~99% (good day) | −$0.17 | +$0.17 | +| Measured uptime (simplified) | You net (per day) | +| --- | --- | +| ~100% (excellent day) | +$0.20 (keep premium) | +| ~99% (good day) | +$0.17 (keep premium) | You keep most or all of the premium. @@ -272,15 +280,15 @@ Payouts scale relative to the day's compute revenue, not the premium collected. -Visible client premiums are lower than backtester output when `sla_r_claim` is above `sla_r_target`. Use `worst_day_loss` as your primary tail-risk reference. The table below illustrates payout at the target boundary only. +Visible client premiums are lower than backtester output when `sla_r_claim` is above `sla_r_target`. Use `worst_day_loss` as your worst single-day payout reference. The table below illustrates payout at the target boundary only. These scenarios show settlement when uptime **drops to or below** the target — they are boundary illustrations, not typical good-uptime days. Settlement uses a **blend of recent and historical uptime** (not just a single day's raw percentage), but the direction is the same — worse uptime means larger client payouts: -| Measured uptime (simplified) | Client pays / receives (per day) | You net (per day) | -| --- | --- | --- | -| At target (~95%) | ~+$42 | ~−$42 | -| Well below target (~90% or less) | ~+$84 (full compute refund) | ~−$84 | +| Measured uptime (simplified) | You net (per day) | +| --- | --- | +| At target (~95%) | −$42 (payout you owe) | +| Well below target (~90% or less) | −$84 (full compute refund owed) | To put the asymmetry in perspective: at ~$0.20/day in premiums, it takes roughly 210 good days to accumulate the $42 you could lose on a single day at the target boundary. The premium is a small fraction of daily compute, while the payout scales against total daily compute revenue. @@ -334,7 +342,12 @@ After you enable SLA, premiums and payouts settle on UTC (Coordinated Universal 1. Open **Host → Billing** (or **Earnings** / **Reports**) for the machine and UTC date range. 2. Look for rows labeled **SLA premium** (client payments you keep) and **SLA payout** (amounts you owe after a miss). Exact menu names may vary; filter by machine ID and date if needed. -3. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. +3. Settlement uses **UTC** calendar days — local-time downtime may appear on the adjacent UTC day. +4. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. + + +SLA daily settlement (premium kept / payout owed) does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. + ### CLI @@ -377,10 +390,14 @@ For API automation only — console users can stop after the Console subsection `GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key (separate from `machine_read` used for the backtester). See [`show earnings`](/api-reference/billing/show-earnings). +This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll no faster than about one request per second per IP; back off on HTTP 429. For day-level per-machine reconciliation at scale, prefer console billing reports over high-frequency API polling. + When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. There is no per-machine daily SLA series in this API. For day-level reconciliation on one machine, use the console earnings report. + +**Fleet operators:** There is no per-machine daily SLA series in the API. Use console day-level reports per machine for reconciliation, or poll `per_machine[].sla_earn` with `last_days=1` per `machid` (mind UTC day boundaries and rate limits). Expect ~N requests per poll cycle for N machines. **Machine-scoped window total:** @@ -402,7 +419,7 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - `sday` / `eday` — UTC day indices (days since 1970-01-01). Prefer `?last_days=N` on the API if you do not want to compute indices manually. - Settlement is evaluated on UTC day boundaries. -The backtester's `historical_sla` replays past settlement and is not a live billing feed. For fleet-scale day-level forensics per machine, use the console or poll `per_machine[].sla_earn` over rolling windows. +The backtester's `historical_sla` replays past settlement and is not a live billing feed. For fleet-scale day-by-day review per machine, use the console or poll `per_machine[].sla_earn` over rolling windows. ## Tips for competitive SLA offers diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index fb39f22c..df1ab3f6 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -4,6 +4,8 @@ Lists a machine for rent. SLA parameters (`--sla_r_target`, `--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). + +For SLA listing via REST, see [SLA Offers — API (for automation)](/host/sla-offers#api-for-automation). Volume and duration options below map to REST request fields on `create_asks/`. ## Usage diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 306265f0..ce4562ff 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -4,6 +4,8 @@ Lists a machine for rent with optional pricing and configuration parameters. SLA parameters (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are **not yet available** in the published Python SDK. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). + +Volume and duration listing parameters (`vol_size`, `vol_price`, `duration`, `price_min_bid`) require the CLI or REST API today — they are not in the SDK signature below. ## Signature From 7fa8ccb4918ab9f3b6d078c0f7d0653b908c1202 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:32:11 -0700 Subject: [PATCH 006/250] docs(sla): address doc-review consensus (cycle 4) Fix API error shapes, UTC day-index docs, confidence/claim clarity, economics table wording, and host overview SLA publish steps. Co-authored-by: Cursor --- api-reference/openapi.yaml | 14 ++-- api-reference/openapi/yaml/list_machine.yaml | 14 ++-- host/hosting-overview.mdx | 12 ++- host/sla-backtester.mdx | 27 ++++--- host/sla-offers.mdx | 80 ++++++++++++-------- 5 files changed, 94 insertions(+), 53 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index cc2c35ef..2cedda7f 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4646,19 +4646,22 @@ paths: type: string example: No such machine(s) for your account '401': - description: Unauthorized + description: Unauthorized — missing permission or invalid API key content: application/json: schema: type: object properties: + success: + type: boolean + example: false error: type: string msg: type: string - example: Missing or invalid API key + example: Your key lacks the machine_write permission group '403': - description: Forbidden + description: Forbidden — machine locked content: application/json: schema: @@ -4667,12 +4670,11 @@ paths: error: type: string enum: - - not_authorized - machine_locked - example: not_authorized + example: machine_locked msg: type: string - example: API key lacks machine_write permission + example: Machine is decommissioned or migration-locked tags: - Machines operationId: listMachine diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 93d860b0..0a10d33d 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -153,19 +153,22 @@ paths: type: string example: No such machine(s) for your account '401': - description: Unauthorized + description: Unauthorized — missing permission or invalid API key content: application/json: schema: type: object properties: + success: + type: boolean + example: false error: type: string msg: type: string - example: Missing or invalid API key + example: Your key lacks the machine_write permission group '403': - description: Forbidden + description: Forbidden — machine locked content: application/json: schema: @@ -174,12 +177,11 @@ paths: error: type: string enum: - - not_authorized - machine_locked - example: not_authorized + example: machine_locked msg: type: string - example: API key lacks machine_write permission + example: Machine is decommissioned or migration-locked tags: - Machines components: diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 44f5ba73..b2ef108e 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -47,7 +47,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (optional):** A reliability guarantee that clients can pay a premium for. Configure via **Set Pricing → SLA** in the console or the REST API — SLA parameters are not yet available in the published CLI/SDK. See [SLA Offers](/host/sla-offers) for parameters and field names. +- **SLA (optional):** Optional uptime coverage for on-demand rentals. Configure in **Set Pricing → SLA**, save pricing, then click **LIST** to publish the offer. SLA parameters are not yet available in the published CLI/SDK. See [Listing an SLA offer → Web console](/host/sla-offers#web-console). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. @@ -237,7 +237,15 @@ Remember that a single machine may have multiple active rental contracts from di For unplanned or unscheduled maintenance, use the CLI and the [`vastai schedule maint`](/host/cli/schedule-maint) command. That will notify the client that you **have** to take the machine down and that they should save their work. You can specify a date and duration. -For SLA-listed machines, scheduled downtime may still count against your reliability target. Uptime credit for maintenance is evaluated case by case and is not guaranteed — give at least 24 hours' notice before extended work. When you schedule maintenance with `vastai schedule maint`, clients with active rentals may be notified automatically. If you want your own alerts (email, webhook, etc.), optionally subscribe via [Host Notifications](/host/notifications) — for example, to `host:maintenance_scheduled`. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). +### If you have SLA enabled on this machine + +SLA-listed machines have additional maintenance obligations: + +- Give at least **24 hours' notice** before planned downtime when possible. +- Use [`vastai schedule maint`](/host/cli/schedule-maint) and configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled` if you want your own alerts. +- Uptime credits during maintenance are evaluated case by case — see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). + +General maintenance guidance above applies to all hosts regardless of SLA. ## Uninstalling diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index dee0b7d8..b0c3915e 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -4,10 +4,16 @@ description: "Replay your machine's historical earnings through SLA math to prev "canonical": "/host/sla-backtester" --- -The **SLA earnings backtester** lets you answer a practical question before you list: *if I had offered SLA at reliability target **`r`** and confidence level **`p`**, how would that have affected my earnings on this machine over the last few months?* (**`r`** = reliability target; **`p`** = host confidence — both defined in [Query parameters](#query-parameters) below.) +The **SLA (Service Level Agreement) earnings backtester** lets you answer a practical question before you list: *if I had offered SLA at reliability target **`r`** and confidence level **`p`**, how would that have affected my earnings on this machine over the last few months?* + +**Console hosts:** use **Set Pricing → SLA** in the web console to preview premiums — you do not need this API. + +**API hosts:** this endpoint replays historical earnings through SLA math to estimate premiums and worst-day payout risk before listing. (**`r`** = reliability target; **`p`** = host confidence — both defined in [Query parameters](#query-parameters) below.) It replays your machine's **real historical compute earnings and uptime** through the same SLA settlement math used in production, then compares the simulated result to what you actually earned from SLA (if anything). +See [Choose your path](#choose-your-path) below. + **Don't want to use the API?** The backtester is optional. Use the web console SLA preview and the economics walkthrough on [SLA Offers](/host/sla-offers#listing-an-sla-offer) to evaluate SLA before listing. The backtester is for hosts who want historical replay via the API. @@ -57,7 +63,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 1. Open **Account → API Keys** in the console and create a key with **`machine_read`** enabled. 2. Copy the token and use `Authorization: Bearer YOUR_API_KEY` in the examples below. See [Create API Key](/api-reference/accounts/create-api-key) and [Authentication](/api-reference/authentication). 3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). The machine must have at least a few weeks of rental activity — new or idle machines should use the console **Set Pricing → SLA** preview instead (the backtester returns `has_data: false` without sufficient history). -4. Run the baseline `curl` below (default date range — no custom dates required) and check `has_data` in the response. +4. Run the baseline request in [Example request](#example-request) and check `has_data` in the response. ## API reference @@ -108,8 +114,9 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ Custom date range (optional — Jan–Apr 2024 for illustration): ```bash -# start_date = Jan 1, 2024; end_date = Apr 1, 2024 -# Tip: on Linux, `date -d '2024-01-01' +%s`; on macOS, `date -j -f '%Y-%m-%d' '2024-01-01' +%s` +# start_date = Jan 1, 2024 UTC; end_date = Apr 1, 2024 UTC +# Linux: date -u -d '2024-01-01' +%s +# macOS: date -u -j -f '%Y-%m-%d' '2024-01-01' +%s # On Windows, use WSL or an online epoch converter. curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667&start_date=1704067200&end_date=1711929600" @@ -187,7 +194,7 @@ A successful response looks like this (fields abbreviated): | Field | Meaning | | --- | --- | | `has_data` | `true` if at least one day in the range had earnings to replay. When `false`, there was no billable rental activity in the range: `covered_days` is `0`, `skipped_days` equals the number of days in the requested window, `daily_results` contains one zero-filled row per day in the window (not an empty array), summary totals are `0.0`, and top-level `reliability` is `null`. Try a wider window or a machine with more rental history. | -| `start_day`, `end_day` | UTC day indices (days since January 1, 1970). Same encoding as `daily_results[].day`. Multiply by 86400 for a Unix timestamp. For example, day `19723` × 86400 = `1704067200` = January 1, 2024 UTC. Most hosts can ignore these and use `start_date`/`end_date` in requests. | +| `start_day`, `end_day` | UTC day indices. The API computes `day = floor(epoch_seconds / 86400)`. Same encoding as `daily_results[].day`. To convert a day index to an approximate UTC date: `date -u -d "@$((day * 86400))" +%Y-%m-%d` (Linux). Do not assume `day × 86400` equals UTC midnight for that calendar day. Most hosts can ignore these and use `start_date`/`end_date` in requests. | | `covered_days` | Days with rental activity replayed through SLA math | | `skipped_days` | Days in the range with no activity (zero-filled in `daily_results`) | | `reliability` | Actual uptime ratio over the range (`total uptime / total active time`) | @@ -202,7 +209,7 @@ A successful response looks like this (fields abbreviated): | `sla` | **Simulated SLA host earnings** for the day. Positive = you keep premium; negative = you pay the client | | `historical_sla` | What you **actually** earned from SLA that day (signed). Zero if you were not offering SLA | -Plot `sla` over time to see which days would have helped or hurt under the chosen parameters. Compare against `historical_sla` to see how simulated economics differ from reality. +Review `sla` day by day in `daily_results` to see which days would have helped or hurt under the chosen parameters. Compare against `historical_sla` to see how simulated economics differ from reality. ### Summary fields @@ -255,14 +262,16 @@ Higher confidence (higher `p`) → tighter spread → lower premiums for clients ## Error responses -| HTTP | `error` | Cause | +| HTTP | `error` / shape | Cause | | --- | --- | --- | -| 401 | — | Missing or invalid Bearer token — see [Authentication](/api-reference/authentication) | +| 403 | `auth_error` | Authorization header missing or invalid session | +| 401 | `auth_error` | API key invalid | +| 401 | authorization `msg` | Valid key but missing `machine_read` (or other scope denial) | +| 403 | `not_owner` | Machine belongs to another host | | 400 | `invalid_range` | `start_date` is after `end_date` | | 400 | `range_too_large` | More than 366 days requested | | 400 | `bad_request` | Schema, bounds, or unknown-parameter failures (for example, `r` or `p` out of range) | | 400 | `invalid_params` | Inputs pass validation but fail inside settlement simulation | -| 403 | `not_owner` | Machine belongs to another host | | 404 | `machine_not_found` | Invalid `machine_id` | | 429 | *(rate limited)* | Too many requests — retry with backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index dec080af..1c04de3b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -12,8 +12,12 @@ This page explains how SLA offers work from the host side — what you are promi SLA settlement is **lopsided by design**: when uptime is good, you keep the premium, but when uptime is bad, client payouts can exceed the premium you collected that day. Premiums and payouts are settled daily based on measured uptime. You can optionally preview SLA economics before listing — use the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). The console preview works on first-time listings. + +Renters: see [Find and rent](/guides/instances/choosing/find-and-rent) and [Pricing](/guides/instances/pricing). SLA applies to **on-demand** rentals only — not interruptible or reserved/prepay. + + -When a client rents a machine with SLA enabled, they pay a small premium on top of the normal hourly rate. If uptime falls below the promised target, credits are applied to their account automatically. SLA applies to on-demand rentals only — not [interruptible](/guides/instances/rental-types) instances. +When a client rents a machine with SLA enabled, they pay a small premium on top of the normal hourly rate (`dph_total` in search includes the SLA premium). If uptime falls below the promised target, credits are applied to their account automatically after **UTC daily settlement** — renters should check **Billing** the following UTC day. SLA applies to on-demand rentals only — not [interruptible](/guides/instances/rental-types) instances. ## Choose your path @@ -78,7 +82,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / -**Confidence in one sentence:** The **preset name** (High / Normal / Wide) controls how **tight your claim spread** is around your target, which changes **client premiums** (tighter → lower premiums, wider → higher premiums). In the console, use the labeled presets rather than raw numbers. The ~83% figure describes how often your machine's actual uptime is expected to meet or exceed your claim — not a separate setting. +**Confidence in one sentence:** The **preset name** (High / Normal / Wide) controls how **tightly premiums are priced around the uptime level you claim you will deliver** (your claim), not around the published reliability target clients see in search. In the console, use the labeled presets rather than raw numbers. The ~83% figure describes how often your machine's actual uptime is expected to meet or exceed your claim — not a separate setting. ### Machine reliability score vs SLA uptime @@ -89,7 +93,9 @@ Do not assume the dashboard score equals SLA uptime. Use **Set Pricing → SLA** ### Confidence presets -If you prefer to think in terms of confidence rather than `sla_sigma_x`, these presets match the shipped defaults. A confidence of ~83% means you believe there is roughly an 83% chance your machine's actual uptime will meet or exceed your claim — higher confidence means lower client premiums. +**This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** + +If you prefer to think in terms of confidence rather than `sla_sigma_x`, these presets match the shipped defaults. At Normal confidence, historical modeling suggests roughly an ~83% chance your machine's measured uptime will meet or exceed your claim — higher confidence means lower client premiums. | Label | Approx. confidence | `sla_sigma_x` | Effect on premium | | --- | --- | --- | --- | @@ -181,20 +187,26 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ Set `end_date` so the offer does not stay open indefinitely — especially important for SLA commitments. See [Offer End Date](/host/hosting-overview#offer-end-date). -Minimal example (claim and confidence use defaults): +Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric payout risk. See [Offer End Date](/host/hosting-overview#offer-end-date). + +Minimal example (includes recommended claim headroom): ```json { "machine": 12345, "price_gpu": 3.50, "end_date": 1735689600, - "sla_r_target": 0.95 + "sla_r_target": 0.95, + "sla_r_claim": 0.99, + "sla_sigma_x": 0.5 } ``` -Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric payout risk. See [Offer End Date](/host/hosting-overview#offer-end-date). + +Setting only `sla_r_target` defaults `sla_r_claim` to the same value, which increases client premiums. For better economics, set **claim above target** (for example, target 95%, claim 99%). + -This creates an offer with target `0.95`, claim `0.95`, and confidence spread `0.5`. +This creates an offer with target `0.95`, claim `0.99`, and confidence spread `0.5`. Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. @@ -215,14 +227,15 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ #### Common errors -| Status | Code | When it happens | +| Status | Code / shape | When it happens | | --- | --- | --- | -| 401 | — | Missing or invalid Bearer token | -| 403 | `not_authorized` | API key lacks `machine_write` or other required permission | +| 401 | `success: false` + `msg` | Missing `machine_write` or other required permission | +| 403 | `machine_locked` | Machine is decommissioned or migration-locked | | 400 | `invalid_args` | Machine ID not found for your account (includes other hosts' machines) | | 400 | `invalid_sla_params` | SLA parameters failed validation | | 400 | `invalid_args` | Malformed or incompatible request body | -| 403 | `machine_locked` | Machine is decommissioned or migration-locked | + +**`machine_locked`:** Returned when a machine is decommissioned or migration-locked. If you are migrating hardware, finish or cancel active rentals first, remove or update the listing as needed, and contact support if the machine remains locked. Existing SLA terms on active contracts remain in force until those contracts end. **Success response (200):** @@ -264,7 +277,7 @@ This premium is what a client searching for 95% reliability would see added to t ### If you meet your claim -**You net** uses host earnings signs: positive = premium you kept; negative = payout you owed the client. +In the **You net** column, values follow host earnings sign conventions: positive means premium you kept; negative means payout you owed the client. | Measured uptime (simplified) | You net (per day) | | --- | --- | @@ -273,6 +286,16 @@ This premium is what a client searching for 95% reliability would see added to t You keep most or all of the premium. +### What if measured uptime is between my target and my claim? + +Example: you publish **target 95%**, claim **99%**, and measured uptime is **~97%**. + +- **Payouts** are evaluated against your published **target** (95%), not your claim. +- Because 97% is above 95%, you typically **owe no SLA payout** for that day. +- **Premiums** are priced from your **claim** (99%) and confidence — a higher claim generally means lower client premiums. + +**Claim** is mainly a pricing knob; **target** is what clients see and what drives payout eligibility. + ### If you miss the target @@ -283,7 +306,7 @@ Payouts scale relative to the day's compute revenue, not the premium collected. Visible client premiums are lower than backtester output when `sla_r_claim` is above `sla_r_target`. Use `worst_day_loss` as your worst single-day payout reference. The table below illustrates payout at the target boundary only. -These scenarios show settlement when uptime **drops to or below** the target — they are boundary illustrations, not typical good-uptime days. Settlement uses a **blend of recent and historical uptime** (not just a single day's raw percentage), but the direction is the same — worse uptime means larger client payouts: +These scenarios show settlement when uptime **drops to or below** the target — they are boundary illustrations, not typical good-uptime days. Payouts for brief outages may be **smaller than the worst-case table** shown below; exact settlement depends on measured uptime for the UTC day and active contract terms: | Measured uptime (simplified) | You net (per day) | | --- | --- | @@ -292,11 +315,7 @@ These scenarios show settlement when uptime **drops to or below** the target — To put the asymmetry in perspective: at ~$0.20/day in premiums, it takes roughly 210 good days to accumulate the $42 you could lose on a single day at the target boundary. The premium is a small fraction of daily compute, while the payout scales against total daily compute revenue. -On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged a premium on top of compute charges for periods when the instance was down. Your maximum SLA loss on any single settlement day is capped at that day's compute revenue, regardless of how the multi-window aggregation evaluates uptime. - - -Production settlement blends recent and historical uptime — not a single raw day — so short outages may not produce the maximum illustrated payout. - +On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged a premium on top of compute charges for periods when the instance was down. Your maximum SLA loss on any single settlement day is capped at that day's compute revenue. ## Risk scenarios @@ -340,10 +359,13 @@ After you enable SLA, premiums and payouts settle on UTC (Coordinated Universal ### Console (recommended for day-to-day checks) -1. Open **Host → Billing** (or **Earnings** / **Reports**) for the machine and UTC date range. -2. Look for rows labeled **SLA premium** (client payments you keep) and **SLA payout** (amounts you owe after a miss). Exact menu names may vary; filter by machine ID and date if needed. -3. Settlement uses **UTC** calendar days — local-time downtime may appear on the adjacent UTC day. -4. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. +1. Go to **Host → Billing** (or **Earnings** / **Reports**). +2. Set the date range to include the UTC day you want to review. +3. Filter by machine ID if available. +4. Look for SLA line items — **positive** = premium you kept that day; **negative** = payout you owed the client. + +**If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). +5. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. SLA daily settlement (premium kept / payout owed) does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. @@ -365,6 +387,8 @@ vastai show earnings --machine_id --start_date $(date -v-7d +%F) --end_date On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. +**Linux (GNU date) — parse SLA fields:** + ```bash vastai show earnings --machine_id --start_date $(date -d '7 days ago' +%F) --end_date $(date +%F) --raw \ | jq '.per_machine[] | {machine_id, sla_earn}' @@ -390,14 +414,10 @@ For API automation only — console users can stop after the Console subsection `GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key (separate from `machine_read` used for the backtester). See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll no faster than about one request per second per IP; back off on HTTP 429. For day-level per-machine reconciliation at scale, prefer console billing reports over high-frequency API polling. +This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll no faster than about one request every two seconds per IP (`threshold=2.0`); back off on HTTP 429. For day-level per-machine reconciliation at scale, prefer console billing reports over high-frequency API polling. -When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. - -There is no per-machine daily SLA series in this API. For day-level reconciliation on one machine, use the console earnings report. - -**Fleet operators:** There is no per-machine daily SLA series in the API. Use console day-level reports per machine for reconciliation, or poll `per_machine[].sla_earn` with `last_days=1` per `machid` (mind UTC day boundaries and rate limits). Expect ~N requests per poll cycle for N machines. +When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. There is no per-machine daily SLA series in this API; use console day-level reports per machine for reconciliation, or poll `per_machine[].sla_earn` with `last_days=1` per `machid` (mind UTC day boundaries and rate limits). Expect ~N requests per poll cycle for N machines. **Machine-scoped window total:** @@ -412,8 +432,8 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ | Field | Good day (meet target) | Bad day (miss target) | | --- | --- | --- | -| `per_machine[].sla_earn` / `summary.total_sla` | Positive (premium kept) | Negative (payout paid) | -| Fleet `per_day[].sla_earn` | Positive (premium kept) | Negative (payout paid) | +| `per_machine[].sla_earn` / `summary.total_sla` | Positive (premium kept) | Negative (payout you owe) | +| Fleet `per_day[].sla_earn` | Positive (premium kept) | Negative (payout you owe) | - `{user_id}` — Your account ID (from **Account → Profile** in the console, or `vastai show user`). - `sday` / `eday` — UTC day indices (days since 1970-01-01). Prefer `?last_days=N` on the API if you do not want to compute indices manually. From 6a1d568a9771cd912b8187dab85dcbb8b4ef9243 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:37:17 -0700 Subject: [PATCH 007/250] docs(sla): address doc-review consensus (cycle 5) Fix confidence preset percentages, console step numbering, economics tail-risk cap, fleet listing workflow, and backtester error table. Co-authored-by: Cursor --- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 24 ++++++++++++------------ host/sla-offers.mdx | 37 ++++++++++++++++++++++++++----------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index b2ef108e..cfcdce51 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -45,7 +45,7 @@ The main offer parameters include: - the pricing for GPUs, internet, storage - the discount schedule param which determines the price difference between [on-demand](/guides/instances/rental-types) and [reserved](/guides/instances/rental-types) instances - the min bid price for [interruptible](/guides/instances/rental-types) instances -- the min_gpu param controlling 'slicing' (explained below) +- the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts - **SLA (optional):** Optional uptime coverage for on-demand rentals. Configure in **Set Pricing → SLA**, save pricing, then click **LIST** to publish the offer. SLA parameters are not yet available in the published CLI/SDK. See [Listing an SLA offer → Web console](/host/sla-offers#web-console). diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index b0c3915e..a05cfdec 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -28,12 +28,16 @@ See [Choose your path](#choose-your-path) below. ## When to use it -Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. If `has_data` is `false`, widen the date range or pick a machine with more activity: +Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. -- **Pick a reliability target** — see how often you would have kept premiums or paid them out on historical data -- **Compare confidence levels** — tighter confidence means lower premiums for clients but more risk to you if uptime slips -- **Stress-test bad weeks** — use the optional flat uptime override to see payout size if reliability dropped -- **Compare to history** — each day includes `historical_sla`, your machine's realized SLA earnings on that day (zero if you were not offering SLA) +If `has_data` is `false`, widen the date range or pick a machine with more rental activity. + +Use the backtester to: + +- Pick a reliability target and confidence before you enable SLA on a listing +- Compare how premium and worst-case payout change across targets +- Stress-test a lower reliability assumption before you commit +- Compare to history — each day includes `historical_sla`, your machine's realized SLA earnings on that day (zero if you were not offering SLA) For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). @@ -264,17 +268,13 @@ Higher confidence (higher `p`) → tighter spread → lower premiums for clients | HTTP | `error` / shape | Cause | | --- | --- | --- | -| 403 | `auth_error` | Authorization header missing or invalid session | -| 401 | `auth_error` | API key invalid | -| 401 | authorization `msg` | Valid key but missing `machine_read` (or other scope denial) | +| 400 | `invalid_range`, `range_too_large`, `bad_request`, `invalid_params` | Invalid query parameters or simulation failure | | 403 | `not_owner` | Machine belongs to another host | -| 400 | `invalid_range` | `start_date` is after `end_date` | -| 400 | `range_too_large` | More than 366 days requested | -| 400 | `bad_request` | Schema, bounds, or unknown-parameter failures (for example, `r` or `p` out of range) | -| 400 | `invalid_params` | Inputs pass validation but fail inside settlement simulation | | 404 | `machine_not_found` | Invalid `machine_id` | | 429 | *(rate limited)* | Too many requests — retry with backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | +For missing or invalid API keys and permission denials (`machine_read`), see [Authentication](/api-reference/authentication). + ## Recommended workflow 1. **Run a baseline backtest** on a machine with at least a few weeks of rental history: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1c04de3b..8b47dc17 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -82,7 +82,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / -**Confidence in one sentence:** The **preset name** (High / Normal / Wide) controls how **tightly premiums are priced around the uptime level you claim you will deliver** (your claim), not around the published reliability target clients see in search. In the console, use the labeled presets rather than raw numbers. The ~83% figure describes how often your machine's actual uptime is expected to meet or exceed your claim — not a separate setting. +**Confidence in one sentence:** The **preset name** (High / Normal / Wide) controls how **tightly premiums are priced around the uptime level you claim you will deliver** (your claim), not around the published reliability target clients see in search. In the console, use the labeled presets rather than raw numbers. The ~83% figure applies to the **High** preset — it describes how often your machine's actual uptime is expected to meet or exceed your claim, not the target percentage itself. ### Machine reliability score vs SLA uptime @@ -95,14 +95,16 @@ Do not assume the dashboard score equals SLA uptime. Use **Set Pricing → SLA** **This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** -If you prefer to think in terms of confidence rather than `sla_sigma_x`, these presets match the shipped defaults. At Normal confidence, historical modeling suggests roughly an ~83% chance your machine's measured uptime will meet or exceed your claim — higher confidence means lower client premiums. +If you prefer to think in terms of confidence rather than `sla_sigma_x`, these presets match the shipped defaults: -| Label | Approx. confidence | `sla_sigma_x` | Effect on premium | +| Label | Approx. chance uptime meets claim | `sla_sigma_x` | Effect on premium | | --- | --- | --- | --- | | High | ~83% | `0.2` | Lowest premiums — you are very sure about your claim | | Normal (default) | ~67% | `0.5` | Balanced default | | Wide | ~50% | `1.0` | Higher premiums — more uncertainty priced in | +Higher preset confidence (tighter spread) → lower client premiums, but less room for uptime to slip before payouts. + ### Validation rules Offers with invalid combinations are rejected at listing time: @@ -136,10 +138,11 @@ Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-cove ### Web console 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. -2. Expand **SLA**. -3. Set **Reliability target** (`sla_r_target`), **Reliability claim** (`sla_r_claim`), and **Confidence** (`sla_sigma_x` or a preset). -4. Save and confirm the SLA premium preview before listing. -5. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. +2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. +3. Expand **SLA**. +4. Set **Reliability target**, **Reliability claim**, and **Confidence** (or a preset). API field names: `sla_r_target`, `sla_r_claim`, `sla_sigma_x`. +5. Save and confirm the SLA premium preview before listing. +6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same as pressing **LIST** or running `vastai list machine`), not a save-only draft. @@ -211,7 +214,17 @@ This creates an offer with target `0.95`, claim `0.99`, and confidence spread `0 Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. -Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. For fleet automation, prefer read-modify-write: `vastai show machines` → merge → `PUT /api/v0/machines/create_asks/`. +Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. For fleet automation, prefer read-modify-write: `vastai show machines --raw` → merge → `PUT /api/v0/machines/create_asks/`. + +### Fleet listing workflow + +For multiple machines, loop sequentially — do not parallelize without backoff: + +1. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields and required base pricing. +2. On `429`, sleep and retry with exponential backoff. +3. On `invalid_sla_params` or `machine_locked`, log the machine ID and continue or abort per your rollout policy. + +See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: @@ -264,9 +277,11 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | Item | Amount | | --- | --- | -| Daily compute (`C`) | ~$84/day ($3.50 × 24 hr) | +| Daily compute (`C`) | ~$84/day ($3.50 × 24 hr GPU only — simplified) | | SLA premium to client | ~**$0.008/hr** (~$0.20/day) | +SLA payouts are capped at that UTC day's total billable earnings — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat `worst_day_loss` from the [SLA backtester](/host/sla-backtester) as the authoritative tail-risk figure before you list. + Premium sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst single-day payout exposure (`worst_day_loss`), not exact client premiums. For authoritative client-visible premiums, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers — not backtester `total_sla` when claim exceeds target. @@ -315,7 +330,7 @@ These scenarios show settlement when uptime **drops to or below** the target — To put the asymmetry in perspective: at ~$0.20/day in premiums, it takes roughly 210 good days to accumulate the $42 you could lose on a single day at the target boundary. The premium is a small fraction of daily compute, while the payout scales against total daily compute revenue. -On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged a premium on top of compute charges for periods when the instance was down. Your maximum SLA loss on any single settlement day is capped at that day's compute revenue. +On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged a premium on top of compute charges for periods when the instance was down. Your maximum SLA loss on any single settlement day is capped at that day's total billable earnings (GPU, storage, and bandwidth). ## Risk scenarios @@ -363,9 +378,9 @@ After you enable SLA, premiums and payouts settle on UTC (Coordinated Universal 2. Set the date range to include the UTC day you want to review. 3. Filter by machine ID if available. 4. Look for SLA line items — **positive** = premium you kept that day; **negative** = payout you owed the client. +5. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. **If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). -5. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. SLA daily settlement (premium kept / payout owed) does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. From a79da883f57630e9694277e3571c8e30bc5f2efa Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:42:18 -0700 Subject: [PATCH 008/250] docs(sla): address doc-review consensus (cycle 6) Clarify hourly vs daily premium framing, promote fleet listing section, fix setup URL consistency, and improve earnings API fleet guidance. Co-authored-by: Cursor --- host/hosting-overview.mdx | 4 ++-- host/sla-offers.mdx | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index cfcdce51..546c8bd3 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -47,7 +47,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (optional):** Optional uptime coverage for on-demand rentals. Configure in **Set Pricing → SLA**, save pricing, then click **LIST** to publish the offer. SLA parameters are not yet available in the published CLI/SDK. See [Listing an SLA offer → Web console](/host/sla-offers#web-console). +- **SLA (optional):** Uptime coverage for on-demand rentals. Configure in **Set Pricing → SLA**, save pricing, then click **LIST** to publish. SLA can increase earnings on good days but expose you to large payouts on bad days — read [SLA Offers → Economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling. SLA parameters are not yet available in the published CLI/SDK. See [Listing an SLA offer → Web console](/host/sla-offers#web-console). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. @@ -255,7 +255,7 @@ To uninstall, use the Vast uninstall script located at https://s3.amazonaws.com/ ### How do I host my machine(s) on Vast? How can I rent my PC? -Hosting on Vast will require some Linux knowledge, as you will be maintaining a server. Our setup guide is [here](https://vast.ai/console/host/setup/). After the first paragraph of the guide there is a link to the hosting agreement. Once you agree, your account will be converted to a hosting account. You can review our [FAQ](https://vast.ai/faq/#Hosting-General) that answers many of your hosting questions. +Hosting on Vast will require some Linux knowledge, as you will be maintaining a server. Our setup guide is [here](https://cloud.vast.ai/host/setup/). After the first paragraph of the guide there is a link to the hosting agreement. Once you agree, your account will be converted to a hosting account. You can review our [FAQ](https://vast.ai/faq/#Hosting-General) that answers many of your hosting questions. ### How do I get an invoice? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 8b47dc17..d668f615 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -4,7 +4,7 @@ description: "Offer reliability guarantees on your machines, set SLA parameters, "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is reliability insurance: the client pays a small daily premium, and if uptime falls short of the agreed target, the client receives a payout from your earnings. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is reliability insurance: the client pays a small hourly SLA add-on included in `dph_total`, and if uptime falls short of the agreed target, the client receives a payout from your earnings. This page explains how SLA offers work from the host side — what you are promising, how pricing is calculated, and what happens when uptime is good or bad. @@ -13,11 +13,11 @@ SLA settlement is **lopsided by design**: when uptime is good, you keep the prem -Renters: see [Find and rent](/guides/instances/choosing/find-and-rent) and [Pricing](/guides/instances/pricing). SLA applies to **on-demand** rentals only — not interruptible or reserved/prepay. +**Renters:** SLA coverage, premiums, and credits are not yet documented on our renter guides. Until a dedicated client SLA page ships, see [What your clients see](#what-your-clients-see) below for a brief summary. -When a client rents a machine with SLA enabled, they pay a small premium on top of the normal hourly rate (`dph_total` in search includes the SLA premium). If uptime falls below the promised target, credits are applied to their account automatically after **UTC daily settlement** — renters should check **Billing** the following UTC day. SLA applies to on-demand rentals only — not [interruptible](/guides/instances/rental-types) instances. +Clients pay a small hourly SLA add-on included in `dph_total` (for example, ~$0.008/hr on top of the base GPU rate). Premiums and payouts are settled once per UTC calendar day — search and the console show the hourly rate; billing reconciles daily. If uptime falls below the promised target, credits are applied automatically after **UTC daily settlement**. SLA applies to on-demand rentals only — not [interruptible](/guides/instances/rental-types) instances. ## Choose your path @@ -53,8 +53,8 @@ Think of an SLA offer as three linked ideas: When a client rents with SLA enabled: -- They pay **compute** (GPU, storage, bandwidth) plus a **daily SLA premium**. -- Each day, Vast measures how long the instance was online and settles the SLA. +- They pay **compute** (GPU, storage, bandwidth) plus a **small hourly SLA add-on** included in `dph_total`. +- Each UTC calendar day, Vast measures how long the instance was online and settles the SLA. - **Good uptime** → you keep the premium for that day. - **Bad uptime** → you pay the client from your earnings (up to the day's compute revenue). @@ -188,7 +188,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ }' ``` -Set `end_date` so the offer does not stay open indefinitely — especially important for SLA commitments. See [Offer End Date](/host/hosting-overview#offer-end-date). +Set `end_date` so the offer does not stay open indefinitely — especially important for SLA commitments. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2025-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2025-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`. Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric payout risk. See [Offer End Date](/host/hosting-overview#offer-end-date). @@ -214,7 +214,14 @@ This creates an offer with target `0.95`, claim `0.99`, and confidence spread `0 Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. -Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. For fleet automation, prefer read-modify-write: `vastai show machines --raw` → merge → `PUT /api/v0/machines/create_asks/`. +Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. For fleet automation, read current settings then merge: + +```bash +vastai show machines --raw | jq '.[] | select(.id==12345) | {id, sla_r_target, sla_r_claim, sla_sigma_x, price_gpu, end_date}' +``` + +Then `PUT /api/v0/machines/create_asks/` with merged fields. + ### Fleet listing workflow @@ -225,7 +232,6 @@ For multiple machines, loop sequentially — do not parallelize without backoff: 3. On `invalid_sla_params` or `machine_locked`, log the machine ID and continue or abort per your rollout policy. See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. - **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: @@ -278,7 +284,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | Item | Amount | | --- | --- | | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr GPU only — simplified) | -| SLA premium to client | ~**$0.008/hr** (~$0.20/day) | +| SLA premium (client pays) | ~**$0.008/hr** (~$0.20/day at 24 hr) | SLA payouts are capped at that UTC day's total billable earnings — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat `worst_day_loss` from the [SLA backtester](/host/sla-backtester) as the authoritative tail-risk figure before you list. @@ -432,7 +438,19 @@ For API automation only — console users can stop after the Console subsection This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll no faster than about one request every two seconds per IP (`threshold=2.0`); back off on HTTP 429. For day-level per-machine reconciliation at scale, prefer console billing reports over high-frequency API polling. -When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. There is no per-machine daily SLA series in this API; use console day-level reports per machine for reconciliation, or poll `per_machine[].sla_earn` with `last_days=1` per `machid` (mind UTC day boundaries and rate limits). Expect ~N requests per poll cycle for N machines. +When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. + +**Quick rules:** +- **One machine:** use `per_machine[].sla_earn` with `machid` set. +- **Fleet:** one request without `machid` returns all machines in `per_machine[]`: + +```bash +curl -s -H "Authorization: Bearer $VAST_API_KEY" \ + "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?last_days=1" \ + | jq '.per_machine[] | {machine_id, sla_earn}' +``` + +Poll no faster than about one request every two seconds. Prefer console billing exports for month-end reconciliation. **Machine-scoped window total:** From 48162e33ec87406761aa7913a90332b489346ce4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:46:45 -0700 Subject: [PATCH 009/250] docs(sla): address doc-review consensus (cycle 7) Fix show machines jq path for partial updates, define dph_total early, and correct backtester economics walkthrough link. Co-authored-by: Cursor --- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index a05cfdec..3593ed01 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -15,7 +15,7 @@ It replays your machine's **real historical compute earnings and uptime** throug See [Choose your path](#choose-your-path) below. -**Don't want to use the API?** The backtester is optional. Use the web console SLA preview and the economics walkthrough on [SLA Offers](/host/sla-offers#listing-an-sla-offer) to evaluate SLA before listing. The backtester is for hosts who want historical replay via the API. +**Don't want to use the API?** The backtester is optional. Use the web console SLA preview and the [economics walkthrough](/host/sla-offers#economics-walkthrough) on SLA Offers to evaluate SLA before listing. The backtester is for hosts who want historical replay via the API. ## Choose your path diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index d668f615..aff58df8 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -4,7 +4,7 @@ description: "Offer reliability guarantees on your machines, set SLA parameters, "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is reliability insurance: the client pays a small hourly SLA add-on included in `dph_total`, and if uptime falls short of the agreed target, the client receives a payout from your earnings. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is reliability insurance: the client pays a small hourly SLA add-on included in **`dph_total`** (dollars per hour total in search — base compute plus SLA premium), and if uptime falls short of the agreed target, the client receives a payout from your earnings. This page explains how SLA offers work from the host side — what you are promising, how pricing is calculated, and what happens when uptime is good or bad. @@ -214,12 +214,14 @@ This creates an offer with target `0.95`, claim `0.99`, and confidence spread `0 Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. -Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. For fleet automation, read current settings then merge: +Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. Before merging partial SLA updates, read current listing fields from `vastai show machine --raw` (or the machine detail API) and confirm the response includes `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, `price_gpu`, and `end_date`: ```bash -vastai show machines --raw | jq '.[] | select(.id==12345) | {id, sla_r_target, sla_r_claim, sla_sigma_x, price_gpu, end_date}' +vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, sla_r_target, sla_r_claim, sla_sigma_x, price_gpu, end_date}' ``` +Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. If SLA fields are missing, use `vastai show machine 12345 --raw` instead. + Then `PUT /api/v0/machines/create_asks/` with merged fields. From e9906cae894403748fbb81114937f5fd69fbbf75 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:54:41 -0700 Subject: [PATCH 010/250] docs(sla): address doc-review consensus (cycle 8) Extend show-machines OpenAPI for SLA read path, add search field mapping, fix daily vs window monitoring examples, uptime measurement, and hosting fixes. Co-authored-by: Cursor --- api-reference/openapi.yaml | 34 ++++++ api-reference/openapi/yaml/show_machines.yaml | 30 +++++ host/hosting-overview.mdx | 22 ++-- host/sla-backtester.mdx | 8 +- host/sla-offers.mdx | 103 ++++++++++++++---- 5 files changed, 161 insertions(+), 36 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 2cedda7f..d2d3d54b 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8804,6 +8804,12 @@ paths: user. + The `--raw` CLI output includes listing and SLA fields (`price_gpu`, `end_date`, + `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, etc.) used for read-modify-write + before partial SLA updates. See SLA Offers partial-update workflow in host + documentation. + + CLI Usage: `vastai show machines [--user_id ]`' operationId: getMachines parameters: @@ -8832,6 +8838,34 @@ paths: name: type: string description: The name of the machine. + price_gpu: + type: number + description: GPU rental price in $/hour (when present in raw listing output). + end_date: + type: number + description: Offer expiration as Unix timestamp (when present in raw listing output). + min_chunk: + type: integer + description: Minimum GPUs rented together (GPU slicing). + sla_r_target: + type: number + description: SLA reliability target (0 to disable; greater than 0 and at most 0.9999 when enabled). + sla_r_claim: + type: number + description: SLA reliability claim (must be greater than or equal to target). + sla_sigma_x: + type: number + description: SLA confidence spread (maps to console High / Normal / Wide presets). + example: + machines: + - id: '12345' + name: my-h100 + price_gpu: 3.5 + end_date: 1735689600 + min_chunk: 1 + sla_r_target: 0.95 + sla_r_claim: 0.99 + sla_sigma_x: 0.5 '401': description: Unauthorized - User authentication failed '429': diff --git a/api-reference/openapi/yaml/show_machines.yaml b/api-reference/openapi/yaml/show_machines.yaml index 4e5c4420..049d370b 100644 --- a/api-reference/openapi/yaml/show_machines.yaml +++ b/api-reference/openapi/yaml/show_machines.yaml @@ -9,6 +9,8 @@ paths: description: | Fetches data for multiple machines associated with the authenticated user. + The `--raw` CLI output includes listing and SLA fields (`price_gpu`, `end_date`, `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, etc.) used for read-modify-write before partial SLA updates. See [SLA Offers — Partial updates](/host/sla-offers#api-for-automation). + CLI Usage: `vastai show machines [--user_id ]` operationId: getMachines parameters: @@ -37,6 +39,34 @@ paths: name: type: string description: The name of the machine. + price_gpu: + type: number + description: GPU rental price in $/hour (when present in raw listing output). + end_date: + type: number + description: Offer expiration as Unix timestamp (when present in raw listing output). + min_chunk: + type: integer + description: Minimum GPUs rented together (GPU slicing). + sla_r_target: + type: number + description: SLA reliability target (0 to disable; greater than 0 and at most 0.9999 when enabled). + sla_r_claim: + type: number + description: SLA reliability claim (must be greater than or equal to target). + sla_sigma_x: + type: number + description: SLA confidence spread (maps to console High / Normal / Wide presets). + example: + machines: + - id: "12345" + name: my-h100 + price_gpu: 3.5 + end_date: 1735689600 + min_chunk: 1 + sla_r_target: 0.95 + sla_r_claim: 0.99 + sla_sigma_x: 0.5 '401': description: Unauthorized - User authentication failed '429': diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 546c8bd3..3e24822d 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -16,7 +16,7 @@ Vast is a GPU marketplace. Hosts sell GPU resources on the marketplace. Hosts ar ## Account setup and hosting agreement -You must create a new account for hosting. If you are using Vast.ai as a client, do not use the same account. A single client and hosting account is not supported and you will quickly run into issues. +You must create a new account for hosting. If you are using Vast.ai as a client, do not use the same account. Using the same account for both client and hosting is not supported and you will quickly run into issues. Once your account is created, open the [host setup guide](https://cloud.vast.ai/host/setup/). There is a link in the first paragraph to the hosting agreement. Read through the agreement. Once you accept, your account will then be converted to a hosting account. You will notice there is now a link to Machines in the navigation, along with some other changes. Your account can now list machines that are running the daemon software. @@ -47,7 +47,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (optional):** Uptime coverage for on-demand rentals. Configure in **Set Pricing → SLA**, save pricing, then click **LIST** to publish. SLA can increase earnings on good days but expose you to large payouts on bad days — read [SLA Offers → Economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling. SLA parameters are not yet available in the published CLI/SDK. See [Listing an SLA offer → Web console](/host/sla-offers#web-console). +- **SLA (optional):** Optional uptime guarantee for on-demand rentals — clients pay a small premium; you may owe payouts if uptime misses your published target. You can list without SLA. See [SLA Offers](/host/sla-offers#economics-walkthrough) before enabling. The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. @@ -141,15 +141,15 @@ In addition to GPU offers, hosts can create volume offers on machines. A volume Allocated storage (that is, storage in use by client rental contracts) is subtracted from the total storage available on a machine, and split up proportionally among the machine's GPUs in remaining GPU offers. -For example, on a machine with 1000Gb of disk available and 2 GPUs, a host can create a volume offer of up to 1000 Gb. +For example, on a machine with 1000 GB of disk available and 2 GPUs, a host can create a volume offer of up to 1000 GB. -If they create a volume offer of 500 Gb, and it is not rented, the machine will be available for rent with 2 offers of 1xGPU 500Gb and 1 offer of 2xGPU 1000Gb. +If they create a volume offer of 500 GB, and it is not rented, the machine will be available for rent with 2 offers of 1xGPU 500 GB and 1 offer of 2xGPU 1000 GB. -If 200 Gb of the volume offer are rented, the GPU offers will reduce to 2 1xGPU 400Gb offers and 1 2xGPU 800Gb offer. The volume offer will still remain, as there is still available space, and update to offer 300Gb. +If 200 GB of the volume offer are rented, the GPU offers will reduce to 2 1xGPU 400 GB offers and 1 2xGPU 800 GB offer. The volume offer will still remain, as there is still available space, and update to offer 300 GB. -Similarly, if stored instances on the machine are taking up 800Gb, the volume offer will reduce to 200Gb. +Similarly, if stored instances on the machine are taking up 800 GB, the volume offer will reduce to 200 GB. -If stored instances are only taking up 400 Gb, the volume offer will not update, as there is still enough space on the machine to cover the volume offer. +If stored instances are only taking up 400 GB, the volume offer will not update, as there is still enough space on the machine to cover the volume offer. ### Listing Volumes @@ -168,7 +168,7 @@ vastai list volume -s -p ``` - Volume offer end dates **must** align with GPU offer end dates. Setting an end date on a volume will not update if there is an existing GPU offer. Setting a GPU offer end date will update volume offer end dates. + Volume offer end dates **must** align with GPU offer end dates. Setting an end date on a volume will not update the GPU offer's end date if a GPU offer already exists. Setting a GPU offer end date will update volume offer end dates. Volume offers will be unlisted when the machine is unlisted. They can additionally be unlisted with the command: @@ -222,9 +222,11 @@ Replace 12345 with your actual machine ID in question. You can see the number of Take the ID number from the first column and use that to create a free instance on your own machine. This example loads the latest pytorch image along with both jupyter and ssh direct launch modes. ```text Text -./vastai create instance --image pytorch/pytorch:latest --jupyter --direct --env '-e TZ=PDT -p 22:22 -p 8080:8080' +vastai create instance --image pytorch/pytorch:latest --jupyter --direct --env '-e TZ=PDT -p 22:22 -p 8080:8080' ``` +Use `./vastai` instead of `vastai` when running from the install directory. + You can then look at your [instance tab](https://cloud.vast.ai/instances/) to make sure that pytorch loaded correctly along with jupyter and ssh. Click on the \<\_ button to get the ssh command to connect to the instance. Test the direct ssh command. Click on the open button to test jupyter. If the button is stuck "connecting" then there is most likely a problem with the port configuration on the router in front of the machine. Once finished, destroy the instance. ## Maintenance @@ -309,7 +311,7 @@ To get an understanding of prices, check our [Market Stats page](https://cloud.v ### Why did the reliability on my machine decrease? -If the machine loses connection or if there is a client instance that does not want to start the machine's reliability will drop. +If the machine loses connection, or if a client instance fails to start, the machine's reliability will drop. ### How do I minimize my reliability dropping? diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 3593ed01..84df6947 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -223,7 +223,7 @@ Review `sla` day by day in `daily_results` to see which days would have helped o | `total_sla` | Net simulated SLA earnings. Positive = SLA would have added income overall | | `total_earnings` | Compute + simulated SLA | | `total_historical_sla` | Sum of realized historical SLA in the range | -| `worst_day_loss` | Largest single-day client payout (your worst simulated loss) | +| `worst_day_loss` | Largest single-day client payout (your worst simulated loss). Always a non-negative dollar amount — unlike signed `sla` / `sla_earn` fields | | `reserve` | Reserved for future use — ignore in production decisions today. | ## Interpreting results @@ -300,7 +300,7 @@ export VAST_API_KEY="YOUR_API_KEY" ```bash for id in $(vastai show machines -q); do - resp=$(curl -sf -H "Authorization: Bearer $VAST_API_KEY" \ + resp=$(curl -s -H "Authorization: Bearer $VAST_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=0.95&p=0.6667" \ || echo '{"error":"request_failed"}') if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then @@ -308,11 +308,11 @@ for id in $(vastai show machines -q); do else echo "$resp" | jq '{machine_id: '"$id"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' fi - sleep 1 + sleep 2 done ``` -Use a `machine_read` key scoped to the machines you own. On `429`, back off per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Parallel requests are not recommended unless you implement backoff. +Expect roughly two seconds per machine minimum (`sleep 2` plus request time). For 50 machines, budget at least a few minutes. Run off-peak before a fleet SLA rollout. On `429`, back off per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Parallel requests are not recommended unless you implement backoff. 3. Compare `worst_day_loss` and `total_sla` across machines. 4. Apply `sla_r_claim` headroom when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index aff58df8..5a4bbc8d 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -13,11 +13,11 @@ SLA settlement is **lopsided by design**: when uptime is good, you keep the prem -**Renters:** SLA coverage, premiums, and credits are not yet documented on our renter guides. Until a dedicated client SLA page ships, see [What your clients see](#what-your-clients-see) below for a brief summary. +**Clients:** see [What your clients see](#what-your-clients-see) below for how SLA appears in search and billing. -Clients pay a small hourly SLA add-on included in `dph_total` (for example, ~$0.008/hr on top of the base GPU rate). Premiums and payouts are settled once per UTC calendar day — search and the console show the hourly rate; billing reconciles daily. If uptime falls below the promised target, credits are applied automatically after **UTC daily settlement**. SLA applies to on-demand rentals only — not [interruptible](/guides/instances/rental-types) instances. +Clients pay a small hourly SLA add-on included in `dph_total` (for example, ~$0.008/hr on top of the base GPU rate). On SLA-listed on-demand offers, coverage is included automatically when the client rents — no separate host-side toggle at rent time. The published **target %** appears in search and the rent flow alongside `dph_total`. Premiums and payouts settle once per UTC calendar day; credits typically post to **Billing** within a few hours after UTC midnight (exact timing can vary). If uptime falls below the promised target, credits are applied automatically. SLA applies to on-demand rentals only — not [interruptible](/guides/instances/rental-types) instances. ## Choose your path @@ -26,6 +26,7 @@ Clients pay a small hourly SLA add-on included in `dph_total` (for example, ~$0. | --- | --- | | Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer) | | Enable or update SLA via API | [Before you enable SLA](#before-you-enable-sla) → [API (for automation)](#api-for-automation) | +| I list with CLI only (no SLA flags yet) | **Set Pricing → SLA** + **LIST** in the console, or REST `PUT /api/v0/machines/create_asks/` — SLA flags are **not** in `vastai list machine` yet | | Monitor payouts after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | ## Before you enable SLA @@ -37,7 +38,7 @@ Before enabling SLA, finish normal listing setup: test your machine, set GPU pri SLA can be enabled on a first-time listing, but you still need base listing fields (GPU price, offer end date, etc.). See [Listing an SLA offer](#listing-an-sla-offer) and [Offer End Date](/host/hosting-overview#offer-end-date). -**Rental types:** SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. If a client attempts to reserve or prepay an SLA-enabled offer, the request is rejected. +**Rental types:** SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible instances on an SLA-enabled machine are not SLA-covered; on-demand contracts on the same machine are. If a client attempts to reserve or prepay an SLA-enabled offer, the request is rejected. - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. @@ -58,7 +59,18 @@ When a client rents with SLA enabled: - **Good uptime** → you keep the premium for that day. - **Bad uptime** → you pay the client from your earnings (up to the day's compute revenue). -Under honest pricing, a host who delivers what they claim should roughly break even on SLA over time — premiums and payouts balance. +Over many good-uptime days, premiums can offset occasional payouts, but a single bad day can exceed months of collected premiums — see [Risk scenarios](#risk-scenarios) and `worst_day_loss` before you commit. + +### How uptime is measured + +SLA uptime is measured at the **rental contract (instance) level** using platform health signals for active on-demand contracts — not your personal SSH session or Jupyter tab. + +- **Instance fails to start** when a client rents → counts against SLA uptime for that contract. +- **Machine-level outage** while contracts are active → affects settlement for those contracts. +- **Brief host reboots** during active rentals may count as downtime depending on duration. +- **Scheduled maintenance** may receive credit case by case — see [Scheduled maintenance](#scheduled-maintenance). + +On sliced machines, SLA settles **per rental contract**. If one GPU slice fails but others remain healthy, only contracts on the affected slice are measured for downtime. ## SLA parameters @@ -89,15 +101,19 @@ When you list or update a machine, set SLA fields via the host console or `PUT / The **reliability score** on the Host Machines page reflects connection and instance-start behavior (and is earnings-weighted). **SLA settlement** measures whether covered instances met your published uptime target for billing purposes. -Do not assume the dashboard score equals SLA uptime. Use **Set Pricing → SLA** in the console or the backtester on historical data to choose `sla_r_target`, `sla_r_claim`, and confidence — not the Machines-page number alone. +Do not assume the dashboard score equals SLA uptime. Before choosing `sla_r_target`: + +1. Open **Host → Machines** → **Set Pricing → SLA** and review the console premium preview at candidate targets. +2. If you have rental history, run the [backtester](/host/sla-backtester) and check top-level `reliability` in the response. +3. Set **target** at or slightly below the uptime level you can sustain; use **claim above target** for competitive premiums. ### Confidence presets -**This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** +**This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** Use the **High / Normal / Wide** presets in the console UI; only set raw `sla_sigma_x` via API after you have saved once in the console. -If you prefer to think in terms of confidence rather than `sla_sigma_x`, these presets match the shipped defaults: +If you prefer to think in terms of confidence rather than `sla_sigma_x`, these presets match the shipped defaults. The probability column below describes **pricing preset tightness**, not a guarantee that uptime will meet your claim: -| Label | Approx. chance uptime meets claim | `sla_sigma_x` | Effect on premium | +| Label | Pricing preset meaning | `sla_sigma_x` | Effect on premium | | --- | --- | --- | --- | | High | ~83% | `0.2` | Lowest premiums — you are very sure about your claim | | Normal (default) | ~67% | `0.5` | Balanced default | @@ -140,7 +156,7 @@ Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-cove 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. -4. Set **Reliability target**, **Reliability claim**, and **Confidence** (or a preset). API field names: `sla_r_target`, `sla_r_claim`, `sla_sigma_x`. +4. Set **Reliability target**, **Reliability claim**, and **Confidence** (or a preset). 5. Save and confirm the SLA premium preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. @@ -174,6 +190,10 @@ Before you call this endpoint, your machine must appear on **Host → Machines** Listing or updating SLA parameters requires an API key with **`machine_write`** permission. Backtesting requires **`machine_read`**. See [API permissions](/api-reference/permissions). + +The example below **adds SLA to an offer that already has base pricing configured**. For a first-time listing, include all required base fields (`price_gpu`, `end_date`, `min_chunk`, storage/bandwidth prices as needed) — see [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). + + ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ @@ -235,6 +255,20 @@ For multiple machines, loop sequentially — do not parallelize without backoff: See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. +```bash +export VAST_API_KEY="YOUR_API_KEY" +for id in $(vastai show machines -q); do + current=$(vastai show machine "$id" --raw) + curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ + -H "Authorization: Bearer $VAST_API_KEY" \ + -H "Content-Type: application/json" \ + -d "$(echo "$current" | jq -c '{machine: (.id|tonumber), price_gpu, end_date, sla_r_target: 0.95, sla_r_claim: 0.99, sla_sigma_x: 0.5}')" + sleep 2 +done +``` + +Log `invalid_sla_params` and `machine_locked` responses; back off on HTTP 429. + **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: ```bash @@ -250,7 +284,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | Status | Code / shape | When it happens | | --- | --- | --- | -| 401 | `success: false` + `msg` | Missing `machine_write` or other required permission | +| 401 | `success: false` + `msg` (+ optional `error`) | Missing `machine_write` or other required permission | | 403 | `machine_locked` | Machine is decommissioned or migration-locked | | 400 | `invalid_args` | Machine ID not found for your account (includes other hosts' machines) | | 400 | `invalid_sla_params` | SLA parameters failed validation | @@ -298,6 +332,22 @@ The economics above assume **claim above target** (headroom): claim (99%) is abo This premium is what a client searching for 95% reliability would see added to the total hourly price in search results (`dph_total` — visible in the console SLA preview or [Search Offers](/api-reference/search/search-offers) results). +### Search / client-visible fields + +When SLA is enabled on an offer, clients see: + +- **`dph_total`** — total $/hour including the SLA premium (authoritative for client-visible all-in pricing). +- **`expected_reliability`** — the advertised SLA target (maps to your `sla_r_target`). +- **`reliability` / `reliability2`** — historical machine reliability scores, **not** your SLA target. + +Verify after listing: + +```bash +vastai search offers 'machine_id=12345' --raw | jq '.[0] | {dph_total, price_gpu, expected_reliability, reliability}' +``` + +Premium sizing uses internal SLA math — use the console preview or `dph_total` above, not backtester `total_sla`, when claim exceeds target. + ### If you meet your claim In the **You net** column, values follow host earnings sign conventions: positive means premium you kept; negative means payout you owed the client. @@ -378,14 +428,14 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m ## Monitoring SLA after listing -After you enable SLA, premiums and payouts settle on UTC (Coordinated Universal Time) day boundaries. +After you enable SLA, premiums and payouts settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). ### Console (recommended for day-to-day checks) 1. Go to **Host → Billing** (or **Earnings** / **Reports**). 2. Set the date range to include the UTC day you want to review. 3. Filter by machine ID if available. -4. Look for SLA line items — **positive** = premium you kept that day; **negative** = payout you owed the client. +4. Look for **SLA** entries in the earnings breakdown — positive amounts are premiums you kept; negative amounts are payouts you owed the client. 5. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. **If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). @@ -410,14 +460,21 @@ vastai show earnings --machine_id --start_date $(date -v-7d +%F) --end_date On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. -**Linux (GNU date) — parse SLA fields:** +**Linux (GNU date) — one UTC day (compare to `worst_day_loss`):** + +```bash +vastai show earnings --machine_id --start_date $(date -u -d 'yesterday' +%F) --end_date $(date -u -d 'yesterday' +%F) --raw \ + | jq '.per_machine[] | select(.machine_id == or .machine_id == "") | {machine_id, sla_earn}' +``` + +**Linux (GNU date) — seven-day window (do not compare directly to single-day `worst_day_loss`):** ```bash vastai show earnings --machine_id --start_date $(date -d '7 days ago' +%F) --end_date $(date +%F) --raw \ - | jq '.per_machine[] | {machine_id, sla_earn}' + | jq '.per_machine[] | select(.machine_id == or .machine_id == "") | {machine_id, sla_earn}' ``` -Positive `sla_earn` = net SLA premium you kept that period; negative = net payout you owe. See the sign-convention table in the API subsection below. +Positive `sla_earn` = net SLA premium you kept that period; negative = net payout you owe. Weekly aggregates are window totals, not daily series — use a one-day range above for day-level checks. ### API (automation) @@ -443,8 +500,8 @@ This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/ra When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine:** use `per_machine[].sla_earn` with `machid` set. -- **Fleet:** one request without `machid` returns all machines in `per_machine[]`: +- **One machine, one UTC day:** use `last_days=1` with `machid` set (or a one-day `start_date`/`end_date` range). There is no per-machine daily SLA series in the API — day-level breakdown for a single machine is easiest in **Host → Billing**. +- **Fleet snapshot:** one request without `machid` returns all machines in `per_machine[]` for the window: ```bash curl -s -H "Authorization: Bearer $VAST_API_KEY" \ @@ -455,14 +512,16 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ Poll no faster than about one request every two seconds. Prefer console billing exports for month-end reconciliation. -**Machine-scoped window total:** +**Machine-scoped one-day total:** ```bash curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?machid=12345&last_days=7" \ - | jq '.per_machine[] | select(.machine_id==12345) | {machine_id, sla_earn}' + "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?machid=12345&last_days=1" \ + | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` +Do **not** compare `last_days=7` totals to single-day `worst_day_loss` from the backtester. + **Sign convention** (same as backtester `sla` / `historical_sla`): | Field | Good day (meet target) | Bad day (miss target) | @@ -472,9 +531,9 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - `{user_id}` — Your account ID (from **Account → Profile** in the console, or `vastai show user`). - `sday` / `eday` — UTC day indices (days since 1970-01-01). Prefer `?last_days=N` on the API if you do not want to compute indices manually. -- Settlement is evaluated on UTC day boundaries. +- Settlement is evaluated on UTC day boundaries. Rows typically update within a few hours after UTC midnight. -The backtester's `historical_sla` replays past settlement and is not a live billing feed. For fleet-scale day-by-day review per machine, use the console or poll `per_machine[].sla_earn` over rolling windows. +The backtester's `historical_sla` replays past settlement and is not a live billing feed. For day-level per-machine reconciliation, use **Host → Billing**; use `last_days=1` API polling only when you need automation. ## Tips for competitive SLA offers From f0238ffdb3fcb650fcee804972eb5bfa35ccb02c Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 20:59:52 -0700 Subject: [PATCH 011/250] docs(sla): address doc-review consensus (cycle 9) Fix SLA opt-in phrasing, fleet listing read-modify-write pattern, UTC monitoring dates, and confidence preset wording. Co-authored-by: Cursor --- host/sla-offers.mdx | 20 +++++++++++--------- snippets/host/cli/list-machine.mdx | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 5a4bbc8d..f25fe3a2 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -52,7 +52,7 @@ Think of an SLA offer as three linked ideas: 2. **Your reliability claim** — what you believe your machine will actually deliver. 3. **Your confidence** — how sure you are about that claim. Tight confidence means you stand behind a narrow range; wide confidence means a wider defensible range and clients pay a higher premium. -When a client rents with SLA enabled: +When a client rents an on-demand instance on your SLA-listed offer, Vast measures uptime against your published target and claim percentages: - They pay **compute** (GPU, storage, bandwidth) plus a **small hourly SLA add-on** included in `dph_total`. - Each UTC calendar day, Vast measures how long the instance was online and settles the SLA. @@ -111,7 +111,7 @@ Do not assume the dashboard score equals SLA uptime. Before choosing `sla_r_targ **This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** Use the **High / Normal / Wide** presets in the console UI; only set raw `sla_sigma_x` via API after you have saved once in the console. -If you prefer to think in terms of confidence rather than `sla_sigma_x`, these presets match the shipped defaults. The probability column below describes **pricing preset tightness**, not a guarantee that uptime will meet your claim: +The **Pricing preset meaning** column below describes what each confidence setting implies for premium sizing — not your uptime target. These presets control pricing spread; the ~83%, ~67%, and ~50% figures describe statistical pricing confidence, not guaranteed uptime: | Label | Pricing preset meaning | `sla_sigma_x` | Effect on premium | | --- | --- | --- | --- | @@ -234,13 +234,13 @@ This creates an offer with target `0.95`, claim `0.99`, and confidence spread `0 Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. -Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. Before merging partial SLA updates, read current listing fields from `vastai show machine --raw` (or the machine detail API) and confirm the response includes `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, `price_gpu`, and `end_date`: +Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. Read current listing fields from `vastai show machines --raw` (filter with `jq` below). See [Show Machines](/api-reference/machines/show-machines) for the documented REST response shape: ```bash vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, sla_r_target, sla_r_claim, sla_sigma_x, price_gpu, end_date}' ``` -Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. If SLA fields are missing, use `vastai show machine 12345 --raw` instead. +Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Then `PUT /api/v0/machines/create_asks/` with merged fields. @@ -258,16 +258,18 @@ See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for ```bash export VAST_API_KEY="YOUR_API_KEY" for id in $(vastai show machines -q); do - current=$(vastai show machine "$id" --raw) - curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ + body=$(vastai show machines --raw | jq -c --arg id "$id" \ + '.machines[] | select((.id|tostring) == $id) | {machine: (.id|tonumber), price_gpu, end_date, min_chunk, sla_r_target: 0.95, sla_r_claim: 0.99, sla_sigma_x: 0.5}') + resp=$(curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer $VAST_API_KEY" \ -H "Content-Type: application/json" \ - -d "$(echo "$current" | jq -c '{machine: (.id|tonumber), price_gpu, end_date, sla_r_target: 0.95, sla_r_claim: 0.99, sla_sigma_x: 0.5}')" + -d "$body") + echo "machine_id=$id response: $resp" sleep 2 done ``` -Log `invalid_sla_params` and `machine_locked` responses; back off on HTTP 429. +Check each response for `success`, `invalid_sla_params`, and `machine_locked` before continuing. Back off on HTTP 429. **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: @@ -402,7 +404,7 @@ Clients receive payouts tied to how far measured uptime falls below the target. ### You set target equal to claim (for example, both 95%) -Premiums are **much higher** because you are not offering any headroom below your claim. Clients only buy this when they need coverage exactly at your stated level. Prefer setting **claim above target** (for example, claim 99%, target 95%) for competitive premiums. +Premiums are **much higher** because you are not offering any headroom — you are not setting **claim above target**. Clients only buy this when they need coverage exactly at your stated level. Prefer setting **claim above target** (for example, claim 99%, target 95%) for competitive premiums. ### You widen confidence (`sla_sigma_x` → 1.0) diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index df1ab3f6..adf465d0 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -5,7 +5,7 @@ Lists a machine for rent. SLA parameters (`--sla_r_target`, `--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). -For SLA listing via REST, see [SLA Offers — API (for automation)](/host/sla-offers#api-for-automation). Volume and duration options below map to REST request fields on `create_asks/`. +For SLA listing via REST, see [SLA Offers — API (for automation)](/host/sla-offers#api-for-automation). Volume and duration options (`-v`, `-z`, `-l`) are available in the CLI today. REST callers should confirm supported `create_asks/` body fields in the [List Machine API reference](/api-reference/machines/list-machine) before sending them — some CLI-only fields may not yet appear in the published OpenAPI schema. ## Usage From 32b62ddcab6368c22d63fbab714ee2889a6b4ca6 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 21:05:19 -0700 Subject: [PATCH 012/250] docs(sla): address doc-review consensus (cycle 10) Add claim headroom guidance, reframe confidence presets, fix search verification jq, and warn against copying backtester p into sla_sigma_x. Co-authored-by: Cursor --- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 3e24822d..4140c70d 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -47,7 +47,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (optional):** Optional uptime guarantee for on-demand rentals — clients pay a small premium; you may owe payouts if uptime misses your published target. You can list without SLA. See [SLA Offers](/host/sla-offers#economics-walkthrough) before enabling. +- **SLA (optional):** Uptime guarantee for on-demand rentals. See [SLA Offers](/host/sla-offers#before-you-enable-sla) to enable and list; read the [economics walkthrough](/host/sla-offers#economics-walkthrough) after you understand target, claim, and confidence. The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f25fe3a2..e0126134 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -52,6 +52,8 @@ Think of an SLA offer as three linked ideas: 2. **Your reliability claim** — what you believe your machine will actually deliver. 3. **Your confidence** — how sure you are about that claim. Tight confidence means you stand behind a narrow range; wide confidence means a wider defensible range and clients pay a higher premium. +**Claim headroom:** Set **Claim** higher than **Target** unless you intentionally want higher client premiums. Clients pay based on the gap between claim and target; payouts still use **Target**. Example: Target 95%, Claim 99%. + When a client rents an on-demand instance on your SLA-listed offer, Vast measures uptime against your published target and claim percentages: - They pay **compute** (GPU, storage, bandwidth) plus a **small hourly SLA add-on** included in `dph_total`. @@ -82,6 +84,10 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Reliability claim | `sla_r_claim` | — (backtester sets claim = target) | Your advertised belief about machine uptime. Defaults to the reliability target if omitted. Must be **≥** the target. Same bounds as target (greater than 0, at most 0.9999). | | Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the claim. Lower = more confident (cheaper for clients). Defaults to `0.5` if omitted. | + +Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x`. They use different scales. Use the preset mapping table below (for example, Normal → `sla_sigma_x=0.5`, which corresponds to backtester `p=0.6667`). + + | Concept | Console | Listing API | Backtester | Client sees | | --- | --- | --- | --- | --- | @@ -111,13 +117,15 @@ Do not assume the dashboard score equals SLA uptime. Before choosing `sla_r_targ **This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** Use the **High / Normal / Wide** presets in the console UI; only set raw `sla_sigma_x` via API after you have saved once in the console. -The **Pricing preset meaning** column below describes what each confidence setting implies for premium sizing — not your uptime target. These presets control pricing spread; the ~83%, ~67%, and ~50% figures describe statistical pricing confidence, not guaranteed uptime: + +Confidence presets control **pricing weight only**, not your uptime obligation. Your obligation is set by **Target**. The statistical weights in the table below (~83% / ~67% / ~50%) describe pricing confidence — do not treat them as uptime targets. + -| Label | Pricing preset meaning | `sla_sigma_x` | Effect on premium | +| Preset | Pricing effect | `sla_sigma_x` | Risk if you miss claim | | --- | --- | --- | --- | -| High | ~83% | `0.2` | Lowest premiums — you are very sure about your claim | -| Normal (default) | ~67% | `0.5` | Balanced default | -| Wide | ~50% | `1.0` | Higher premiums — more uncertainty priced in | +| **High** | Tightest pricing (lowest client premiums) | `0.2` | Highest premium sensitivity | +| **Normal** (default) | Balanced | `0.5` | Moderate | +| **Wide** | Widest pricing band | `1.0` | Lowest premium sensitivity | Higher preset confidence (tighter spread) → lower client premiums, but less room for uptime to slip before payouts. @@ -156,7 +164,7 @@ Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-cove 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. -4. Set **Reliability target**, **Reliability claim**, and **Confidence** (or a preset). +4. Set **Reliability target**, **Reliability claim**, and **Confidence** (or a preset). Set **Claim** higher than **Target** (for example, 99% claim / 95% target) unless you want higher premiums. 5. Save and confirm the SLA premium preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. @@ -345,7 +353,7 @@ When SLA is enabled on an offer, clients see: Verify after listing: ```bash -vastai search offers 'machine_id=12345' --raw | jq '.[0] | {dph_total, price_gpu, expected_reliability, reliability}' +vastai search offers 'machine_id=12345 verified=any' --raw | jq '.offers[0] | {dph_total, expected_reliability, reliability, reliability2}' ``` Premium sizing uses internal SLA math — use the console preview or `dph_total` above, not backtester `total_sla`, when claim exceeds target. @@ -451,13 +459,13 @@ SLA daily settlement (premium kept / payout owed) does not currently emit host w **Linux (GNU date):** ```bash -vastai show earnings --machine_id --start_date $(date -d '7 days ago' +%F) --end_date $(date +%F) +vastai show earnings --machine_id --start_date $(date -u -d '7 days ago' +%F) --end_date $(date -u +%F) ``` **macOS:** ```bash -vastai show earnings --machine_id --start_date $(date -v-7d +%F) --end_date $(date +%F) +vastai show earnings --machine_id --start_date $(date -u -v-7d +%F) --end_date $(date -u +%F) ``` On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. @@ -472,7 +480,7 @@ vastai show earnings --machine_id --start_date $(date -u -d 'yesterday' +%F **Linux (GNU date) — seven-day window (do not compare directly to single-day `worst_day_loss`):** ```bash -vastai show earnings --machine_id --start_date $(date -d '7 days ago' +%F) --end_date $(date +%F) --raw \ +vastai show earnings --machine_id --start_date $(date -u -d '7 days ago' +%F) --end_date $(date -u +%F) --raw \ | jq '.per_machine[] | select(.machine_id == or .machine_id == "") | {machine_id, sla_earn}' ``` @@ -502,7 +510,7 @@ This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/ra When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** use `last_days=1` with `machid` set (or a one-day `start_date`/`end_date` range). There is no per-machine daily SLA series in the API — day-level breakdown for a single machine is easiest in **Host → Billing**. +- **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` (UTC day indices). The CLI flags `--start_date` and `--end_date` map internally to those fields — they are not separate REST query parameter names on `machine-earnings/`. - **Fleet snapshot:** one request without `machid` returns all machines in `per_machine[]` for the window: ```bash From efdafd2bb2c1bd237e78d3f87bcd407155950e71 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 21:09:41 -0700 Subject: [PATCH 013/250] docs(sla): address doc-review consensus (cycle 11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add console-first onboarding note, Save-vs-LIST update path, fix fleet listing O(n²) pattern, and clarify reboot SLA risk wording. Co-authored-by: Cursor --- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 29 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 4140c70d..6dd2bda0 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -47,7 +47,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (optional):** Uptime guarantee for on-demand rentals. See [SLA Offers](/host/sla-offers#before-you-enable-sla) to enable and list; read the [economics walkthrough](/host/sla-offers#economics-walkthrough) after you understand target, claim, and confidence. +- **SLA (uptime guarantee):** Optional add-on for on-demand listings. You set three console knobs: **Target** (what clients see), **Claim** (what you expect to deliver), and **Confidence** (how tightly you price around that expectation). Start with [How it works (plain English)](/host/sla-offers#how-it-works-plain-english), then read the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e0126134..46ec4c1a 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -46,6 +46,16 @@ SLA can be enabled on a first-time listing, but you still need base listing fiel ## How it works (plain English) + +In **Host → Machines → Set Pricing → SLA** you set three knobs only: + +- **Target** — the uptime % clients see in search (your public promise). +- **Claim** — what you expect to deliver (often above Target for pricing headroom). +- **Confidence** — how tightly you price around that expectation (**High / Normal / Wide** — not an uptime %). + +The API field names and backtester aliases below are for automation. Skip them if you use the web console only. + + Think of an SLA offer as three linked ideas: 1. **Reliability target** — the uptime level the listing is priced around (for example, 95% or 99%). @@ -69,7 +79,7 @@ SLA uptime is measured at the **rental contract (instance) level** using platfor - **Instance fails to start** when a client rents → counts against SLA uptime for that contract. - **Machine-level outage** while contracts are active → affects settlement for those contracts. -- **Brief host reboots** during active rentals may count as downtime depending on duration. +- **Brief host reboots** during active rentals may count as downtime if they exceed the platform's measurement window for that UTC day. Vast does not publish a fixed second-level threshold in host docs — treat unplanned reboots as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance) with at least 24 hours' notice when possible. - **Scheduled maintenance** may receive credit case by case — see [Scheduled maintenance](#scheduled-maintenance). On sliced machines, SLA settles **per rental contract**. If one GPU slice fails but others remain healthy, only contracts on the affected slice are measured for downtime. @@ -115,7 +125,7 @@ Do not assume the dashboard score equals SLA uptime. Before choosing `sla_r_targ ### Confidence presets -**This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** Use the **High / Normal / Wide** presets in the console UI; only set raw `sla_sigma_x` via API after you have saved once in the console. +**This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** Use the **High / Normal / Wide** presets in the console UI. Only set raw `sla_sigma_x` via the API if you need a value outside those presets. Confidence presets control **pricing weight only**, not your uptime obligation. Your obligation is set by **Target**. The statistical weights in the table below (~83% / ~67% / ~50%) describe pricing confidence — do not treat them as uptime targets. @@ -168,6 +178,14 @@ Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-cove 5. Save and confirm the SLA premium preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. +#### Updating SLA on an already-listed machine + +If the machine is already **listed** (you previously clicked **LIST** or listed via CLI/REST): + +1. Open **Host → Machines → Set Pricing → SLA**, set Target, Claim, and Confidence, then click **Save**. +2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. +3. Verify in search: `dph_total` includes the SLA add-on and `expected_reliability` matches your Target (see [Search / client-visible fields](#search--client-visible-fields)). + In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same as pressing **LIST** or running `vastai list machine`), not a save-only draft. @@ -265,8 +283,9 @@ See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for ```bash export VAST_API_KEY="YOUR_API_KEY" +machines=$(vastai show machines --raw) for id in $(vastai show machines -q); do - body=$(vastai show machines --raw | jq -c --arg id "$id" \ + body=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id) | {machine: (.id|tonumber), price_gpu, end_date, min_chunk, sla_r_target: 0.95, sla_r_claim: 0.99, sla_sigma_x: 0.5}') resp=$(curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer $VAST_API_KEY" \ @@ -277,7 +296,7 @@ for id in $(vastai show machines -q); do done ``` -Check each response for `success`, `invalid_sla_params`, and `machine_locked` before continuing. Back off on HTTP 429. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: @@ -434,7 +453,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **Listing rejected (`invalid_sla_params`)** — Re-check target, claim, and `sla_sigma_x` against [validation rules](#validation-rules). - **Unexpected payout** — Review uptime; re-run the backtester with a low `reliability` stress value (for example `0.01`). -- **Severe outage** — Disable SLA on new contracts (`sla_r_target=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. +- **Severe outage** — Disable SLA on new contracts: open **Host → Machines** → **Set Pricing → SLA**, set target to `0` (or use API `sla_r_target=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. ## Monitoring SLA after listing From a9a21cf32ab1753f23211a682e56c610da050bc5 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 21:13:42 -0700 Subject: [PATCH 014/250] docs(sla): address doc-review consensus (cycle 12) Fix sliced-machine search verification, clarify reliability filter vs expected_reliability, and align machine-scoped sla_earn guidance. Co-authored-by: Cursor --- api-reference/openapi.yaml | 2 +- api-reference/openapi/yaml/show_earnings.yaml | 2 +- host/sla-offers.mdx | 11 +++++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index d2d3d54b..3ae40bde 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -7822,7 +7822,7 @@ paths: description: | Retrieves the earnings history for a specified time range and optionally per machine. - **Fleet scope:** `per_day[]` (including `sla_earn`) is always fleet-wide for the authenticated host, even when `machid` is set. For machine-scoped SLA totals, use `per_machine[].sla_earn` and `summary.total_sla`. + **Fleet scope:** `per_day[]` (including `sla_earn`) is always fleet-wide for the authenticated host, even when `machid` is set. For machine-scoped SLA totals, use `per_machine[].sla_earn`. CLI Usage: `vastai show earnings [options]` security: diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 62580d78..7b47b313 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -14,7 +14,7 @@ paths: description: | Retrieves the earnings history for a specified time range and optionally per machine. - **Note:** `per_day[]` aggregates SLA earnings across your entire fleet for each UTC day, even when `machid` is set. For machine-scoped SLA totals, use `per_machine[].sla_earn` or `summary.total_sla`. + **Note:** `per_day[]` aggregates SLA earnings across your entire fleet for each UTC day, even when `machid` is set. For machine-scoped SLA totals, use `per_machine[].sla_earn`. CLI Usage: `vastai show earnings [options]` security: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 46ec4c1a..5e2f1228 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -369,10 +369,13 @@ When SLA is enabled on an offer, clients see: - **`expected_reliability`** — the advertised SLA target (maps to your `sla_r_target`). - **`reliability` / `reliability2`** — historical machine reliability scores, **not** your SLA target. -Verify after listing: +**Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the SLA target. The published SLA target appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, post-filter on `expected_reliability > 0` (or your minimum target); do not use the `reliability` filter as an SLA selector. + +Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand): ```bash -vastai search offers 'machine_id=12345 verified=any' --raw | jq '.offers[0] | {dph_total, expected_reliability, reliability, reliability2}' +vastai search offers 'machine_id=12345 verified=any' --raw \ + | jq '[.offers[] | select(.is_bid == false) | {id, num_gpus, dph_total, expected_reliability, reliability}]' ``` Premium sizing uses internal SLA math — use the console preview or `dph_total` above, not backtester `total_sla`, when claim exceeds target. @@ -526,7 +529,7 @@ For API automation only — console users can stop after the Console subsection This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll no faster than about one request every two seconds per IP (`threshold=2.0`); back off on HTTP 429. For day-level per-machine reconciliation at scale, prefer console billing reports over high-frequency API polling. -When you pass `machid`, use `per_machine[].sla_earn` and `summary.total_sla` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. +When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. Do not assume `summary.total_sla` is machine-scoped when `machid` is set — prefer `per_machine[].sla_earn`. **Quick rules:** - **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` (UTC day indices). The CLI flags `--start_date` and `--end_date` map internally to those fields — they are not separate REST query parameter names on `machine-earnings/`. @@ -555,7 +558,7 @@ Do **not** compare `last_days=7` totals to single-day `worst_day_loss` from the | Field | Good day (meet target) | Bad day (miss target) | | --- | --- | --- | -| `per_machine[].sla_earn` / `summary.total_sla` | Positive (premium kept) | Negative (payout you owe) | +| `per_machine[].sla_earn` | Positive (premium kept) | Negative (payout you owe) | | Fleet `per_day[].sla_earn` | Positive (premium kept) | Negative (payout you owe) | - `{user_id}` — Your account ID (from **Account → Profile** in the console, or `vastai show user`). From cb187da78731194a70566d900a6a4bb24ee968a2 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 6 Jul 2026 21:42:41 -0700 Subject: [PATCH 015/250] docs(sla): regenerate openapi.yaml from source YAMLs --- api-reference/openapi.yaml | 110 ++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 50 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 3ae40bde..f0328c46 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4496,20 +4496,14 @@ paths: /api/v0/machines/create_asks: put: summary: list machine - description: 'Creates or updates ask contracts for a machine to list it for - rent on the vast.ai platform. - - Allows setting offer pricing, rental types, end dates, discount rates, - and SLA parameters. - - - SLA request-body fields (sla_r_target, sla_r_claim, sla_sigma_x) are - supported on this REST endpoint. The published CLI and SDK do not yet expose - them — use the host console (Set Pricing → SLA) or REST/curl until CLI/SDK - support ships. - - - CLI Usage (non-SLA fields): `vastai list machine [options]`' + description: "Creates or updates ask contracts for a machine to list it for\ + \ rent on the vast.ai platform.\nAllows setting offer pricing, rental types,\ + \ end dates, discount rates, and SLA parameters.\n\nSLA request-body fields\ + \ (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are supported on this REST\ + \ endpoint. The published CLI and SDK do not yet expose them \u2014 use the\ + \ host console (**Set Pricing \u2192 SLA**) or REST/`curl` until CLI/SDK support\ + \ ships.\n\nCLI Usage (non-SLA fields): `vastai list machine \ + \ [options]`" security: - BearerAuth: [] requestBody: @@ -4561,18 +4555,26 @@ paths: format: float minimum: 0 maximum: 0.9999 - description: "Client reliability coverage target. Values above 0 enable\ - \ SLA on the offer.\nMust be greater than 0 and at most 0.9999\ - \ when enabling SLA; exactly 1.0 is rejected.\nSet to 0 to disable\ - \ SLA. Legacy alias: sla_reliability.\n" + description: 'Client reliability coverage target. Values above 0 + enable SLA on the offer. + + Must be greater than 0 and at most 0.9999 when enabling SLA; exactly + 1.0 is rejected. + + Set to 0 to disable SLA. Legacy alias: sla_reliability. + + ' sla_r_claim: type: number format: float minimum: 0 maximum: 0.9999 - description: "Host reliability claim. Must be greater than 0, at\ - \ most 0.9999, and greater than or equal to sla_r_target.\nDefaults\ - \ to sla_r_target if omitted.\n" + description: 'Host reliability claim. Must be greater than 0, at + most 0.9999, and greater than or equal to sla_r_target. + + Defaults to sla_r_target if omitted. + + ' sla_sigma_x: type: number format: float @@ -4628,7 +4630,8 @@ paths: user_id: 67890 extended: 1 new_contracts: [] - upd_contracts: [1] + upd_contracts: + - 1 '400': description: Bad Request content: @@ -4646,7 +4649,7 @@ paths: type: string example: No such machine(s) for your account '401': - description: Unauthorized — missing permission or invalid API key + description: "Unauthorized \u2014 missing permission or invalid API key" content: application/json: schema: @@ -4661,7 +4664,7 @@ paths: type: string example: Your key lacks the machine_write permission group '403': - description: Forbidden — machine locked + description: "Forbidden \u2014 machine locked" content: application/json: schema: @@ -7819,12 +7822,16 @@ paths: /api/v0/users/{user_id}/machine-earnings: get: summary: show earnings - description: | - Retrieves the earnings history for a specified time range and optionally per machine. + description: 'Retrieves the earnings history for a specified time range and + optionally per machine. + - **Fleet scope:** `per_day[]` (including `sla_earn`) is always fleet-wide for the authenticated host, even when `machid` is set. For machine-scoped SLA totals, use `per_machine[].sla_earn`. + **Note:** `per_day[]` aggregates SLA earnings across your entire fleet for + each UTC day, even when `machid` is set. For machine-scoped SLA totals, use + `per_machine[].sla_earn`. - CLI Usage: `vastai show earnings [options]` + + CLI Usage: `vastai show earnings [options]`' security: - BearerAuth: [] parameters: @@ -7922,7 +7929,8 @@ paths: type: number sla_earn: type: number - description: Net SLA earnings for this machine over the window. + description: Net SLA earnings for this machine over the + window. per_day: type: array items: @@ -7940,7 +7948,9 @@ paths: type: number sla_earn: type: number - description: Net host SLA settlement for the UTC day. Positive when the host keeps premium income; negative when the host pays the client. + description: Net host SLA settlement for the UTC day. Positive + when the host keeps premium income; negative when the + host pays the client. '400': description: Bad Request - Invalid input syntax content: @@ -8800,17 +8810,12 @@ paths: /api/v0/machines: get: summary: show machines - description: 'Fetches data for multiple machines associated with the authenticated - user. - - - The `--raw` CLI output includes listing and SLA fields (`price_gpu`, `end_date`, - `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, etc.) used for read-modify-write - before partial SLA updates. See SLA Offers partial-update workflow in host - documentation. - - - CLI Usage: `vastai show machines [--user_id ]`' + description: "Fetches data for multiple machines associated with the authenticated\ + \ user.\n\nThe `--raw` CLI output includes listing and SLA fields (`price_gpu`,\ + \ `end_date`, `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, etc.) used for\ + \ read-modify-write before partial SLA updates. See [SLA Offers \u2014 Partial\ + \ updates](/host/sla-offers#api-for-automation).\n\nCLI Usage: `vastai show\ + \ machines [--user_id ]`" operationId: getMachines parameters: - name: user_id @@ -8840,22 +8845,27 @@ paths: description: The name of the machine. price_gpu: type: number - description: GPU rental price in $/hour (when present in raw listing output). + description: GPU rental price in $/hour (when present in + raw listing output). end_date: type: number - description: Offer expiration as Unix timestamp (when present in raw listing output). + description: Offer expiration as Unix timestamp (when present + in raw listing output). min_chunk: type: integer description: Minimum GPUs rented together (GPU slicing). sla_r_target: type: number - description: SLA reliability target (0 to disable; greater than 0 and at most 0.9999 when enabled). + description: SLA reliability target (0 to disable; greater + than 0 and at most 0.9999 when enabled). sla_r_claim: type: number - description: SLA reliability claim (must be greater than or equal to target). + description: SLA reliability claim (must be greater than + or equal to target). sla_sigma_x: type: number - description: SLA confidence spread (maps to console High / Normal / Wide presets). + description: SLA confidence spread (maps to console High + / Normal / Wide presets). example: machines: - id: '12345' @@ -9177,16 +9187,16 @@ paths: minimum: 0 exclusiveMinimum: true maximum: 1 - description: Optional flat uptime override (greater than 0 and at most 1) for - all replayed days. Exactly 0 is rejected. + description: Optional flat uptime override (greater than 0 and at most 1) + for all replayed days. Exactly 0 is rejected. - name: beta in: query schema: type: number format: float default: 0.5 - description: Backtest-only timescale weighting. Default 0.5 when omitted. Not - used in live settlement. Contact support before changing. + description: Backtest-only timescale weighting. Default 0.5 when omitted. + Not used in live settlement. Contact support before changing. responses: '200': description: Successful response From f0d03569d508af3b4cd04731adf07263435aeef0 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 13:40:23 -0700 Subject: [PATCH 016/250] docs(sla): align host/client guides to v5 claim model and SLA charge wording Hosts publish claim/confidence only; clients choose target at search. Replace insurance/premium language with SLA charge per HOST-2752 compliance notes. Co-authored-by: Cursor --- api-reference/openapi.yaml | 92 ++--- api-reference/openapi/yaml/list_machine.yaml | 35 +- api-reference/openapi/yaml/show_earnings.yaml | 2 +- api-reference/openapi/yaml/show_machines.yaml | 13 +- api-reference/openapi/yaml/sla_backtest.yaml | 6 +- cli/reference/search-offers.mdx | 6 + docs.json | 1 + .../HOST-2752-SLA-API-Documentation.md | 37 ++ guides/instances/choosing/find-and-rent.mdx | 2 + guides/instances/choosing/sla-coverage.mdx | 189 +++++++++++ host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 73 ++-- host/sla-offers.mdx | 317 ++++++++---------- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 2 +- 15 files changed, 492 insertions(+), 287 deletions(-) create mode 100644 docs/release-notes/HOST-2752-SLA-API-Documentation.md create mode 100644 guides/instances/choosing/sla-coverage.mdx diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index f0328c46..6fc62732 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4499,11 +4499,13 @@ paths: description: "Creates or updates ask contracts for a machine to list it for\ \ rent on the vast.ai platform.\nAllows setting offer pricing, rental types,\ \ end dates, discount rates, and SLA parameters.\n\nSLA request-body fields\ - \ (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are supported on this REST\ - \ endpoint. The published CLI and SDK do not yet expose them \u2014 use the\ - \ host console (**Set Pricing \u2192 SLA**) or REST/`curl` until CLI/SDK support\ - \ ships.\n\nCLI Usage (non-SLA fields): `vastai list machine \ - \ [options]`" + \ (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on\ + \ this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target`\ + \ / legacy `sla_reliability` are ignored \u2014 clients choose coverage at\ + \ search/rent time. The published CLI and SDK do not yet expose SLA fields\ + \ \u2014 use the host console (**Set Pricing \u2192 SLA**) or REST/`curl`\ + \ until CLI/SDK support ships.\n\nCLI Usage (non-SLA fields): `vastai list\ + \ machine [options]`" security: - BearerAuth: [] requestBody: @@ -4550,41 +4552,49 @@ paths: type: number format: float description: Maximum discount rate allowed for prepaid credits - sla_r_target: + sla_r_claim: type: number format: float minimum: 0 maximum: 0.9999 - description: 'Client reliability coverage target. Values above 0 - enable SLA on the offer. + description: 'Host reliability claim. Values above 0 enable SLA + on the offer. Must be greater than 0 and at most 0.9999 when enabling SLA; exactly 1.0 is rejected. - Set to 0 to disable SLA. Legacy alias: sla_reliability. + Set to 0 to disable SLA on new rentals. ' - sla_r_claim: + sla_sigma_x: type: number format: float - minimum: 0 - maximum: 0.9999 - description: 'Host reliability claim. Must be greater than 0, at - most 0.9999, and greater than or equal to sla_r_target. + description: "Host confidence spread \u2014 how wide your belief\ + \ is around the claim.\nMust be greater than 0 and at most 3.0.\ + \ Defaults to 0.5 when enabling SLA.\n" + sla_max_beta: + type: number + format: float + description: 'Optional term capping how path-dependent a client''s + timescale mix can be. - Defaults to sla_r_target if omitted. + Must be in (0, 1) and at least the default beta derived at your + claim. ' - sla_sigma_x: + sla_r_target: type: number format: float - description: "Host confidence spread \u2014 how wide your belief\ - \ is around the claim.\nMust be greater than 0 and at most 3.0.\ - \ Defaults to 0.5.\n" + description: 'Ignored on asks. Client coverage target is supplied + at search/rent time + + (`target_reliability`), not set by the host. + + ' sla_reliability: type: number format: float - description: Legacy alias for sla_r_target. + description: Legacy alias for sla_r_target; ignored on asks. responses: '200': description: Successful response @@ -4624,7 +4634,8 @@ paths: success: true you_sent: machine: 12345 - sla_r_target: 0.95 + sla_r_claim: 0.99 + sla_sigma_x: 0.5 results: - machine_id: 12345 user_id: 67890 @@ -4644,6 +4655,8 @@ paths: enum: - invalid_args - invalid_sla_params + - sla_not_approved + - sla_daemon_outdated example: invalid_sla_params msg: type: string @@ -7949,8 +7962,8 @@ paths: sla_earn: type: number description: Net host SLA settlement for the UTC day. Positive - when the host keeps premium income; negative when the - host pays the client. + when the host keeps the SLA charge; negative when the + host credits the client. '400': description: Bad Request - Invalid input syntax content: @@ -8812,10 +8825,9 @@ paths: summary: show machines description: "Fetches data for multiple machines associated with the authenticated\ \ user.\n\nThe `--raw` CLI output includes listing and SLA fields (`price_gpu`,\ - \ `end_date`, `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, etc.) used for\ - \ read-modify-write before partial SLA updates. See [SLA Offers \u2014 Partial\ - \ updates](/host/sla-offers#api-for-automation).\n\nCLI Usage: `vastai show\ - \ machines [--user_id ]`" + \ `end_date`, `sla_r_claim`, `sla_sigma_x`, etc.) used for read-modify-write\ + \ before partial SLA updates. See [SLA Offers \u2014 Partial updates](/host/sla-offers#api-for-automation).\n\ + \nCLI Usage: `vastai show machines [--user_id ]`" operationId: getMachines parameters: - name: user_id @@ -8854,18 +8866,16 @@ paths: min_chunk: type: integer description: Minimum GPUs rented together (GPU slicing). - sla_r_target: - type: number - description: SLA reliability target (0 to disable; greater - than 0 and at most 0.9999 when enabled). sla_r_claim: type: number - description: SLA reliability claim (must be greater than - or equal to target). + description: Host reliability claim. Values above 0 mean + SLA is enabled on the ask. sla_sigma_x: type: number - description: SLA confidence spread (maps to console High - / Normal / Wide presets). + description: SLA confidence spread around the claim. + sla_max_beta: + type: number + description: Optional cap on client timescale mix (beta). example: machines: - id: '12345' @@ -8873,7 +8883,6 @@ paths: price_gpu: 3.5 end_date: 1735689600 min_chunk: 1 - sla_r_target: 0.95 sla_r_claim: 0.99 sla_sigma_x: 0.5 '401': @@ -9131,7 +9140,7 @@ paths: description: 'Replays a machine''s historical compute earnings and uptime through SLA settlement math - to preview premiums and payouts before listing with SLA. + to preview SLA charges and credits before listing with SLA. Requires `machine_read` permission. See [SLA Earnings Backtester](/host/sla-backtester) @@ -9154,8 +9163,8 @@ paths: minimum: 0 exclusiveMinimum: true maximum: 0.9999 - description: Reliability target to simulate (greater than 0 and at most 0.9999). - Used as both target and claim. Exactly 1.0 is rejected. + description: Reliability level to simulate (greater than 0 and at most 0.9999). + Used as both claim and client target in the simulation. Exactly 1.0 is rejected. - name: p in: query schema: @@ -9195,8 +9204,9 @@ paths: type: number format: float default: 0.5 - description: Backtest-only timescale weighting. Default 0.5 when omitted. - Not used in live settlement. Contact support before changing. + description: "Timescale mix override. For non-admins this is ignored \u2014\ + \ the API derives beta from r (same default a client targeting r would get).\ + \ Admins may override for analysis." responses: '200': description: Successful response diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 0a10d33d..c23e8eed 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -14,7 +14,7 @@ paths: Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. - SLA request-body fields (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are supported on this REST endpoint. The published CLI and SDK do not yet expose them — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. + SLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are ignored — clients choose coverage at search/rent time. The published CLI and SDK do not yet expose SLA fields — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. CLI Usage (non-SLA fields): `vastai list machine [options]` security: @@ -63,33 +63,37 @@ paths: type: number format: float description: Maximum discount rate allowed for prepaid credits - sla_r_target: + sla_r_claim: type: number format: float minimum: 0 maximum: 0.9999 description: | - Client reliability coverage target. Values above 0 enable SLA on the offer. + Host reliability claim. Values above 0 enable SLA on the offer. Must be greater than 0 and at most 0.9999 when enabling SLA; exactly 1.0 is rejected. - Set to 0 to disable SLA. Legacy alias: sla_reliability. - sla_r_claim: + Set to 0 to disable SLA on new rentals. + sla_sigma_x: type: number format: float - minimum: 0 - maximum: 0.9999 description: | - Host reliability claim. Must be greater than 0, at most 0.9999, and greater than or equal to sla_r_target. - Defaults to sla_r_target if omitted. - sla_sigma_x: + Host confidence spread — how wide your belief is around the claim. + Must be greater than 0 and at most 3.0. Defaults to 0.5 when enabling SLA. + sla_max_beta: type: number format: float description: | - Host confidence spread — how wide your belief is around the claim. - Must be greater than 0 and at most 3.0. Defaults to 0.5. + Optional term capping how path-dependent a client's timescale mix can be. + Must be in (0, 1) and at least the default beta derived at your claim. + sla_r_target: + type: number + format: float + description: | + Ignored on asks. Client coverage target is supplied at search/rent time + (`target_reliability`), not set by the host. sla_reliability: type: number format: float - description: Legacy alias for sla_r_target. + description: Legacy alias for sla_r_target; ignored on asks. responses: '200': description: Successful response @@ -129,7 +133,8 @@ paths: success: true you_sent: machine: 12345 - sla_r_target: 0.95 + sla_r_claim: 0.99 + sla_sigma_x: 0.5 results: - machine_id: 12345 user_id: 67890 @@ -148,6 +153,8 @@ paths: enum: - invalid_args - invalid_sla_params + - sla_not_approved + - sla_daemon_outdated example: invalid_sla_params msg: type: string diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 7b47b313..5fe90ee1 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -132,7 +132,7 @@ paths: type: number sla_earn: type: number - description: Net host SLA settlement for the UTC day. Positive when the host keeps premium income; negative when the host pays the client. + description: Net host SLA settlement for the UTC day. Positive when the host keeps the SLA charge; negative when the host credits the client. '400': description: Bad Request - Invalid input syntax content: diff --git a/api-reference/openapi/yaml/show_machines.yaml b/api-reference/openapi/yaml/show_machines.yaml index 049d370b..761bd7a9 100644 --- a/api-reference/openapi/yaml/show_machines.yaml +++ b/api-reference/openapi/yaml/show_machines.yaml @@ -9,7 +9,7 @@ paths: description: | Fetches data for multiple machines associated with the authenticated user. - The `--raw` CLI output includes listing and SLA fields (`price_gpu`, `end_date`, `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, etc.) used for read-modify-write before partial SLA updates. See [SLA Offers — Partial updates](/host/sla-offers#api-for-automation). + The `--raw` CLI output includes listing and SLA fields (`price_gpu`, `end_date`, `sla_r_claim`, `sla_sigma_x`, etc.) used for read-modify-write before partial SLA updates. See [SLA Offers — Partial updates](/host/sla-offers#api-for-automation). CLI Usage: `vastai show machines [--user_id ]` operationId: getMachines @@ -48,15 +48,15 @@ paths: min_chunk: type: integer description: Minimum GPUs rented together (GPU slicing). - sla_r_target: - type: number - description: SLA reliability target (0 to disable; greater than 0 and at most 0.9999 when enabled). sla_r_claim: type: number - description: SLA reliability claim (must be greater than or equal to target). + description: Host reliability claim. Values above 0 mean SLA is enabled on the ask. sla_sigma_x: type: number - description: SLA confidence spread (maps to console High / Normal / Wide presets). + description: SLA confidence spread around the claim. + sla_max_beta: + type: number + description: Optional cap on client timescale mix (beta). example: machines: - id: "12345" @@ -64,7 +64,6 @@ paths: price_gpu: 3.5 end_date: 1735689600 min_chunk: 1 - sla_r_target: 0.95 sla_r_claim: 0.99 sla_sigma_x: 0.5 '401': diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index f782b825..eab06390 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -13,7 +13,7 @@ paths: operationId: slaBacktest description: | Replays a machine's historical compute earnings and uptime through SLA settlement math - to preview premiums and payouts before listing with SLA. + to preview SLA charges and credits before listing with SLA. Requires `machine_read` permission. See [SLA Earnings Backtester](/host/sla-backtester) for usage guide. security: @@ -34,7 +34,7 @@ paths: minimum: 0 exclusiveMinimum: true maximum: 0.9999 - description: Reliability target to simulate (greater than 0 and at most 0.9999). Used as both target and claim. Exactly 1.0 is rejected. + description: Reliability level to simulate (greater than 0 and at most 0.9999). Used as both claim and client target in the simulation. Exactly 1.0 is rejected. - name: p in: query schema: @@ -71,7 +71,7 @@ paths: type: number format: float default: 0.5 - description: Backtest-only timescale weighting. Default 0.5 when omitted. Not used in live settlement. Contact support before changing. + description: Timescale mix override. For non-admins this is ignored — the API derives beta from r (same default a client targeting r would get). Admins may override for analysis. responses: '200': description: Successful response diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 598ea681..4d24bacd 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -81,6 +81,9 @@ bool = True | False # reliable single RTX 3090, no conflicts with stopped instances vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=False' +# SLA offers: host claim ≥ 99%, your coverage target 95% (see SLA Coverage) +vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --order dph_total + # datacenter GPUs with minimum compute capability and TFLOPs vastai search offers 'compute_cap > 610 total_flops > 5 datacenter=True' @@ -145,6 +148,9 @@ vastai search offers 'cpu_arch=arm64' | `pci_gen` | float | PCIE generation | | `pcie_bw` | float | PCIE bandwidth (CPU to GPU) | | `reliability` | float | machine reliability score (see FAQ for explanation) | +| `expected_reliability` | float | host SLA claim (`sla_r_claim`); `0` when SLA is off | +| `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | +| `target_reliability` | float | your desired SLA coverage level; drives SLA charge in `dph_total` | | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | diff --git a/docs.json b/docs.json index 9082fe96..89bb9457 100644 --- a/docs.json +++ b/docs.json @@ -42,6 +42,7 @@ "pages": [ "guides/instances/choosing/overview", "guides/instances/choosing/find-and-rent", + "guides/instances/choosing/sla-coverage", "guides/instances/choosing/instance-types", "guides/instances/choosing/templates", "guides/instances/choosing/reserved-instances" diff --git a/docs/release-notes/HOST-2752-SLA-API-Documentation.md b/docs/release-notes/HOST-2752-SLA-API-Documentation.md new file mode 100644 index 00000000..23ef8f96 --- /dev/null +++ b/docs/release-notes/HOST-2752-SLA-API-Documentation.md @@ -0,0 +1,37 @@ +# HOST-2752: Host & client SLA documentation + +**Branch:** `HOST-2752-SLA-API-Documentation` +**Base:** `origin/main` +**Scope:** User-facing SLA docs aligned to v5 ask/search model and compliance wording. + +## Summary + +Documents SLA for hosts and clients under the current design: hosts publish a **claim** and **confidence** (`sla_r_claim`, `sla_sigma_x`); clients choose **target** at search/rent (`target_reliability`). User-facing copy uses **SLA charge** (not premium) and avoids insurance/betting language. + +## Details + +### Guides + +| Page | Path | Audience | +| --- | --- | --- | +| SLA Offers | `/host/sla-offers` | Hosts — claim/confidence listing, economics, monitoring | +| SLA Earnings Backtester | `/host/sla-backtester` | Hosts — historical replay (`r` = claim=target in sim) | +| SLA Coverage | `/guides/instances/choosing/sla-coverage` | Clients — search filters, charges, credits | + +### Model corrections vs earlier drafts + +- `sla_r_target` is **not** host-settable on asks (ignored if sent). +- SLA activates on `sla_r_claim > 0`; disable with `sla_r_claim = 0`. +- Optional `sla_max_beta` documented for advanced hosts. +- Backtester `beta` is derived from `r` for non-admins. +- Billing note: intended compute billed; compensation via settlement credits. + +### OpenAPI / nav + +- `list_machine.yaml`, `show_machines.yaml`, `sla_backtest.yaml`, `show_earnings.yaml` updated; `openapi.yaml` regenerated. +- `docs.json` adds client SLA Coverage under Find & rent. +- Search CLI docs list `has_sla`, `expected_reliability`, `target_reliability`. + +## Compliance wording + +Forbidden in user docs: insurance, premium (prefer **SLA charge**), betting, gambling, bet. API field names such as `slaPremiumPerHour` are documented as the SLA charge rate without using “premium” as prose. diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index f7f249fd..235e1e98 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -80,6 +80,8 @@ Click on the "Change Template" button to bring up the template config menu that ![Edit](/images/find-and-rent-edit.webp) +Some offers include an optional **SLA** reliability guarantee. To filter and compare SLA-backed rentals, see [SLA Coverage](/guides/instances/choosing/sla-coverage). + ## Common Questions ### I can't search for instances. I am getting the error "Error: invalid\_request 0 is not a valid search op" diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx new file mode 100644 index 00000000..886c5f1b --- /dev/null +++ b/guides/instances/choosing/sla-coverage.mdx @@ -0,0 +1,189 @@ +--- +title: "SLA Coverage" +description: "Rent GPU instances with reliability guarantees. Learn how SLA charges, credits, and search filters work." +"canonical": "/guides/instances/choosing/sla-coverage" +--- + +Some Vast.ai offers include a **Service Level Agreement (SLA)** — a reliability guarantee bundled with your on-demand rental. You choose a reliability **target** when you search, pay a small hourly **SLA charge** on top of compute, and if measured reliability falls short of that target, you receive settlement credits. + +This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. + + +You do not post escrow or collateral for SLA. You pay the SLA charge while the instance runs. Settlement happens automatically on a daily cadence. + + +## What SLA protects + +SLA is a **contractual, per-rental** reliability guarantee with automatic daily settlement. It is **not** the same as [verification](/host/understanding-verification) or the **reliability score** shown on offer cards — those are platform trust signals. + +For SLA-covered on-demand contracts: + +- Compute is billed for the **intended** rental day (offline time is tracked as an outage in reliability measurements). +- **Settlement credits** compensate you when measured reliability falls short of your chosen target. +- On strong-reliability days, you simply pay the SLA charge with no credit. + +SLA is most useful for **long-running production workloads** where unexpected downtime has a real cost beyond the hourly rate. + +## How pricing works + +Total hourly cost with SLA: + +``` +total ≈ GPU + storage + bandwidth + SLA charge +``` + +The SLA charge depends on: + +| Factor | Where it comes from | Effect | +| --- | --- | --- | +| Your reliability target | Your search filter (`target_reliability`) | Higher target → higher SLA charge | +| Host reliability claim | `expected_reliability` on the offer | Higher claim → lower SLA charge (at a given target) | +| Host confidence | Derived from `sla_sigma_x` on the offer | Tighter confidence → lower SLA charge | + +**Rule of thumb:** pick a target **at or below** the host's claim for the best value. If you ask for 99% coverage on a host who only claims 95%, the SLA charge is much higher than asking for 95% on a host who claims 99%. + +### Example: H100 at $3.50/hr GPU + +Searching with **target reliability 95%** on an offer where the host **claims 99%** with normal confidence: + +| Cost component | Approx. rate | +| --- | --- | +| GPU compute | $3.50/hr | +| SLA charge | ~$0.008/hr | +| **Total** | ~$3.51/hr | + +The SLA charge is a small fraction of compute when the host's claim comfortably exceeds your target. + +## Finding SLA offers + +### Search filters + +Use these filters in [Search](https://cloud.vast.ai/create/) or the [search offers API](/api-reference/search/search-offers): + +| Filter | Meaning | Example | +| --- | --- | --- | +| `target_reliability` | Your desired reliability level. Also drives SLA charge calculation and ranking. | `target_reliability=0.95` | +| `has_sla` | Restrict to offers with (or without) SLA enabled. | `has_sla=true` | +| `expected_reliability` | Filter by the host's advertised claim. | `expected_reliability>=0.99` | + +**CLI examples:** + +```bash +# SLA offers where the host claims at least 99% reliability +vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' + +# Compare total cost including SLA charge +vastai search offers 'has_sla=true target_reliability=0.95 num_gpus=1' --order dph_total +``` + +When you set `target_reliability`, search results include: + +| Response field | Meaning | +| --- | --- | +| `search.slaPremiumPerHour` | SLA charge for this offer at your target (API field name; this is the SLA charge rate) | +| `dph_total` | Total hourly cost **including** the SLA charge | +| `expected_reliability` | Host's reliability claim | + +Hover the price breakdown on an offer card to see GPU, storage, bandwidth, and the SLA charge separately. + + +When you search with an SLA target, **reserved-instance discounts are not applied** to the displayed total. SLA charges are never discounted. + + +### Comparing offers + +Two offers at the same GPU price can have very different SLA costs: + +| Offer | GPU/hr | Host claim | Your target | SLA charge/hr | +| --- | --- | --- | --- | --- | +| A | $3.50 | 99% | 95% | ~$0.008 | +| B | $3.50 | 95% | 95% | much higher | + +Offer A is dramatically cheaper on SLA because the host claims more headroom above your target. Always compare **`dph_total`**, not just GPU price, when SLA matters. + +Search ranking also accounts for SLA cost — offers with expensive coverage at your target rank lower per dollar of performance. + +## What happens after you rent + +When you rent an SLA-backed offer: + +1. **Contract terms lock in** — your reliability target, the host's claim, and confidence spread are fixed for that rental. +2. **Daily billing** — you pay compute plus the SLA charge each day. +3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. +4. **Credits appear in billing** — positive credits improve your balance; strong days mean you paid the SLA charge with no credit. + +### How reliability is measured + +Each day, the platform tracks how long your instance was online. Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: + +- A single bad hour hurts, but does not always trigger the maximum credit. +- A pattern of unreliable uptime produces larger credits over time. +- One strong day after a weak week does not instantly reset everything. + +Scheduled maintenance with adequate notice may be credited toward reliability. Unplanned outages count fully. + +### Credit scenarios (simplified) + +Using the H100 example ($84/day compute, ~$0.20/day SLA charge, target 95%, host claim 99%): + +| Day's measured reliability (simplified) | What you pay | What you receive | Your net vs no-SLA baseline | +| --- | --- | --- | --- | +| Excellent (~100%) | $84 compute + $0.20 SLA charge | — | −$0.20 | +| Good (~99%) | $84 + $0.20 | Small credit | Roughly −$0.17 | +| At target (~95%) | $84 + $0.20 | ~$42 credit | ~+$42 | +| Severe outage (~90% or less) | $84 + $0.20 | ~$84 credit | ~+$84 | + + +Production settlement uses the multi-window reliability blend described above, not a single raw daily percentage. Treat these rows as directional, not exact invoice amounts. + + +### Settlement timing + +- Settlement runs **once per day** for the previous billing day. +- Credits accumulate on your instance charges and transfer to your account balance. +- When your contract ends, any remaining unsettled days are resolved at close. + +## Viewing SLA on active instances + +On the [Instances](https://cloud.vast.ai/instances/) page, price details for SLA rentals include the SLA charge rate alongside GPU and storage costs. + +The [show instances API](/api-reference/instances/show-instances) exposes SLA fields on each contract: + +| Field | Meaning | +| --- | --- | +| `target_reliability` | Your coverage target | +| `sla_r_claim` | Host's claim | +| `sla_sigma_x` | Host's confidence spread | +| `search.slaPremiumPerHour` | Current SLA charge rate (API field name) | + +Filter active instances with `has_sla=true` in the query. + +## When SLA is not available + +- **Prepaid / reserved-only flows** may reject SLA parameters. Use on-demand rentals for SLA coverage. +- Offers without SLA (`expected_reliability = 0` / `has_sla=false`) are excluded when you filter with `has_sla=true` or set a positive `target_reliability`. +- If SLA parameters on an offer are invalid for your target, search may flag an SLA pricing error instead of showing a charge. + +## FAQ + +### Do I need SLA for every rental? + +No. For short experiments or fault-tolerant batch jobs, standard on-demand rentals without SLA may be enough. SLA is for workloads where reliability has a real dollar cost. + +### Can I change my reliability target mid-rental? + +No. The target is fixed when the contract is created. End the instance and rent again with a different search filter if you need a different level. + +### Does SLA replace verification? + +No. Verification is a platform quality signal. SLA is a financial guarantee on a specific contract. A verified machine can still have SLA; an unverified machine may also offer SLA. + +### Where do I see historical SLA credits? + +Check your billing history and instance charges. SLA line items appear alongside compute charges for each settled day. + +## Related documentation + +- [SLA Offers (hosts)](/host/sla-offers) — how hosts configure and price SLA listings +- [Finding & Renting Instances](/guides/instances/choosing/find-and-rent) — search basics and offer cards +- [Instance Pricing](/guides/instances/pricing) — on-demand, interruptible, and reserved pricing diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 6dd2bda0..9bd0029c 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -47,7 +47,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (uptime guarantee):** Optional add-on for on-demand listings. You set three console knobs: **Target** (what clients see), **Claim** (what you expect to deliver), and **Confidence** (how tightly you price around that expectation). Start with [How it works (plain English)](/host/sla-offers#how-it-works-plain-english), then read the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. +- **SLA (uptime guarantee):** Optional add-on for on-demand listings. You set a **Claim** (reliability you believe you can deliver) and **Confidence** (how tightly SLA charges are priced around that claim). Clients choose their own reliability **target** at search/rent time. Start with [How it works (plain English)](/host/sla-offers#how-it-works-plain-english), then read the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. Renters: see [SLA Coverage](/guides/instances/choosing/sla-coverage). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 84df6947..6bac61be 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -1,16 +1,16 @@ --- title: "SLA Earnings Backtester" -description: "Replay your machine's historical earnings through SLA math to preview premiums and payouts before listing." +description: "Replay your machine's historical earnings through SLA math to preview SLA charges and credits before listing." "canonical": "/host/sla-backtester" --- -The **SLA (Service Level Agreement) earnings backtester** lets you answer a practical question before you list: *if I had offered SLA at reliability target **`r`** and confidence level **`p`**, how would that have affected my earnings on this machine over the last few months?* +The **SLA (Service Level Agreement) earnings backtester** lets you answer a practical question before you list: *if clients had rented with reliability target **`r`** and I offered SLA at confidence **`p`**, how would that have affected my earnings on this machine over the last few months?* -**Console hosts:** use **Set Pricing → SLA** in the web console to preview premiums — you do not need this API. +**Console hosts:** use **Set Pricing → SLA** in the web console to preview SLA charges — you do not need this API. -**API hosts:** this endpoint replays historical earnings through SLA math to estimate premiums and worst-day payout risk before listing. (**`r`** = reliability target; **`p`** = host confidence — both defined in [Query parameters](#query-parameters) below.) +**API hosts:** this endpoint replays historical earnings through SLA math to estimate SLA charges and worst-day credit risk before listing. (**`r`** = reliability level used as both claim and target in the simulation; **`p`** = host confidence — both defined in [Query parameters](#query-parameters) below.) -It replays your machine's **real historical compute earnings and uptime** through the same SLA settlement math used in production, then compares the simulated result to what you actually earned from SLA (if anything). +It replays your machine's **real historical compute earnings and reliability** through the same SLA settlement math used in production, then compares the simulated result to what you actually earned from SLA (if anything). See [Choose your path](#choose-your-path) below. @@ -34,8 +34,8 @@ If `has_data` is `false`, widen the date range or pick a machine with more renta Use the backtester to: -- Pick a reliability target and confidence before you enable SLA on a listing -- Compare how premium and worst-case payout change across targets +- Pick a reliability claim and confidence before you enable SLA on a listing +- Compare how SLA charge and worst-case credit change across targets - Stress-test a lower reliability assumption before you commit - Compare to history — each day includes `historical_sla`, your machine's realized SLA earnings on that day (zero if you were not offering SLA) @@ -43,21 +43,21 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). ## How it works -1. You choose a machine, date range, reliability target (`r`), and confidence (`p`). +1. You choose a machine, date range, reliability level (`r`), and confidence (`p`). 2. The API loads per-day earnings from your machine's rental history. 3. For each active day, it computes GPU, storage, and bandwidth earnings plus simulated SLA host earnings. 4. It returns a day-by-day breakdown and summary totals. -**Simulated vs listing parameters.** In the backtester, reliability target and claim are both set to **`r`** — the backtester cannot set `sla_r_claim` above `sla_r_target`. Claim-headroom simulation is console-only today. When you actually list a machine, you can set **`sla_r_claim` above `sla_r_target`** for lower client premiums. Workflow: backtest `worst_day_loss` at your target, then verify visible premiums in **Set Pricing → SLA** (or `dph_total` in search) before listing with claim above target. +**Simulated vs listing parameters.** In the backtester, reliability **claim and client target are both set to `r`**. That is a conservative what-if: it pretends every client targeted your claim. When you list, you set only **`sla_r_claim`** (and `sla_sigma_x`); clients choose their own `target_reliability` at search/rent time. Workflow: backtest `worst_day_loss` at a candidate claim level, then verify visible SLA charges in **Set Pricing → SLA** (or `dph_total` in search at realistic client targets) before listing. -**Active vs idle days.** **Idle days** are days with no rental earnings on the machine (no active compute rental). These days typically produce no SLA premium or payout in the simulation. Days with no rental activity appear in the results as zero-filled rows but do not count toward `covered_days`. Only days with actual earnings are replayed through SLA math. +**Active vs idle days.** **Idle days** are days with no rental earnings on the machine (no active compute rental). These days typically produce no SLA charge or credit in the simulation. Days with no rental activity appear in the results as zero-filled rows but do not count toward `covered_days`. Only days with actual earnings are replayed through SLA math. **Simulation vs live listing** -- The backtester sets claim equal to target and may show higher premiums than live listing or the console preview. -- For client-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console. +- The backtester sets claim equal to target and may show higher SLA charges than live listing when clients choose targets below your claim. +- For client-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or search with a realistic `target_reliability`. - For tail risk, trust `worst_day_loss`, not headline `total_sla`. -- The backtester defaults `beta` to `0.5` when omitted. Live SLA settlement does **not** use this default — weighting is fixed when you list. Treat `total_sla` as a tail-risk estimate, not an exact live preview. +- Timescale mix (`β`) is derived from `r` for non-admin callers (same default a client targeting `r` would get). Admin overrides of `beta` are ignored for non-admins. ## Before you start @@ -81,21 +81,17 @@ GET /api/v0/host/sla_backtest/ Requires Bearer authentication. This endpoint is rate-limited like other host API endpoints — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) for retry guidance. - -Find your API key under **Account → API Keys** (requires [`machine_read`](/api-reference/permissions) permission). See [Create API Key](/api-reference/accounts/create-api-key) if you need a new key. Your machine ID appears on the [Host Machines page](https://cloud.vast.ai/host/machines) or via [`vastai show machines`](/host/cli/show-machines). - - ### Query parameters | Parameter | Required | Description | | --- | --- | --- | | `machine_id` | Yes | ID of your machine | -| `r` | Yes | Reliability target to simulate (greater than 0 and at most **0.9999**). Used as both target and claim. Example: `0.95` = 95%. Exactly `1.0` is rejected. | +| `r` | Yes | Reliability level to simulate (greater than 0 and at most **0.9999**). Used as **both claim and client target** in the simulation. Example: `0.95` = 95%. Exactly `1.0` is rejected. | | `p` | No | Host confidence (greater than 0 and **less than 1** — not equal to 1). Maps to the same spread used when listing with `sla_sigma_x` — see [Confidence values](#confidence-values-p) below. Default: `0.6667` (normal confidence, ≈ 67%). | | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | | `reliability` | No | Optional flat uptime override (greater than 0 and at most 1). Ignores historical uptime — useful for what-if analysis. Use `0.01` to approximate near-total downtime; `0` is rejected with `400 bad_request`. | -| `beta` | No | Backtest-only timescale weighting. Default `0.5` when omitted. **Not used in live settlement.** Contact support before changing. | +| `beta` | No | Timescale mix override. For non-admins this is **ignored** — the API derives β from `r` (same default a client targeting `r` would get). Admins may override for analysis. | ### Limits @@ -133,7 +129,7 @@ Compare two confidence levels on the same history: curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667" -# High confidence (~83%) — tighter spread, lower simulated premiums +# High confidence (~83%) — tighter spread, lower simulated SLA charges curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.83" ``` @@ -210,7 +206,7 @@ A successful response looks like this (fields abbreviated): | --- | --- | | `gpu`, `storage`, `bandwidth` | That day's compute earnings breakdown ($) | | `uptime` | Uptime fraction for the day (0–1), or your flat override if set | -| `sla` | **Simulated SLA host earnings** for the day. Positive = you keep premium; negative = you pay the client | +| `sla` | **Simulated SLA host earnings** for the day. Positive = you keep the SLA charge; negative = you credit the client | | `historical_sla` | What you **actually** earned from SLA that day (signed). Zero if you were not offering SLA | Review `sla` day by day in `daily_results` to see which days would have helped or hurt under the chosen parameters. Compare against `historical_sla` to see how simulated economics differ from reality. @@ -223,46 +219,46 @@ Review `sla` day by day in `daily_results` to see which days would have helped o | `total_sla` | Net simulated SLA earnings. Positive = SLA would have added income overall | | `total_earnings` | Compute + simulated SLA | | `total_historical_sla` | Sum of realized historical SLA in the range | -| `worst_day_loss` | Largest single-day client payout (your worst simulated loss). Always a non-negative dollar amount — unlike signed `sla` / `sla_earn` fields | +| `worst_day_loss` | Largest single-day client credit (your worst simulated loss). Always a non-negative dollar amount — unlike signed `sla` / `sla_earn` fields | | `reserve` | Reserved for future use — ignore in production decisions today. | ## Interpreting results ### Mostly positive `sla` values -Your historical uptime was strong relative to the target. SLA would likely have been a net positive — small premiums on good days, few days with payouts. +Your historical reliability was strong relative to the simulated target. SLA would likely have been a net positive — small SLA charges on strong days, few days with credits. ### Negative `sla` on specific days -Those days had uptime below your chosen target. The magnitude shows how much you would have paid out. If you see clusters of negative days, consider a lower target, wider confidence, or fixing reliability before listing SLA. +Those days had reliability below the simulated target. The magnitude shows how much you would have credited. If you see clusters of negative days, consider a lower claim, wider confidence, or fixing reliability before listing SLA. ### `total_sla` near zero -Break-even territory — premiums and payouts roughly balance. Typical when your actual uptime matches your stated target. +Break-even territory — SLA charges and credits roughly balance. Typical when your actual reliability matches the simulated target. ### `total_sla` strongly negative -Under the simulated parameters, SLA would have cost you money over this window. Either improve uptime, lower the target, or widen confidence before listing. +Under the simulated parameters, SLA would have cost you money over this window. Either improve reliability, lower the claim, or widen confidence before listing. ### Using `reliability` override -Setting `reliability=0.90` while keeping `r=0.99` answers: *if every active day had 90% uptime, how bad would SLA payouts get?* Use this to understand worst-case payout exposure before committing to a high target. +Setting `reliability=0.90` while keeping `r=0.99` answers: *if every active day had 90% uptime, how bad would SLA credits get?* Use this to understand worst-case credit exposure before committing to a high claim. ## Confidence values (`p`) -**`p` and `sla_sigma_x` use different scales** — do not copy numeric values between them. For example, `p=0.5` (Wide confidence) maps to `sla_sigma_x ≈ 1.0`, not `0.5`. Use the table below to translate between the two. +**`p` and `sla_sigma_x` use different scales** — do not copy numeric values between them. For example, `p=0.5` (wide confidence) maps to `sla_sigma_x ≈ 1.0`, not `0.5`. Use the table below to translate between the two. -The backtester accepts **`p`** (confidence) instead of `sla_sigma_x`. The mappings below match the presets used when listing: +The backtester accepts **`p`** (confidence) instead of `sla_sigma_x`. The mappings below match common listing values: | Confidence `p` | Approx. label | Listing equivalent | | --- | --- | --- | -| `0.83` | High | `sla_sigma_x ≈ 0.2` | +| `0.83` | Tight | `sla_sigma_x ≈ 0.2` | | `0.6667` | Normal (default) | `sla_sigma_x ≈ 0.5` | | `0.50` | Wide | `sla_sigma_x ≈ 1.0` | -Higher confidence (higher `p`) → tighter spread → lower premiums for clients, but less room for uptime to slip before payouts. +Higher confidence (higher `p`) → tighter spread → lower SLA charges for clients at a given target, but less room for reliability to slip before credits grow. ## Error responses @@ -278,14 +274,14 @@ For missing or invalid API keys and permission denials (`machine_read`), see [Au ## Recommended workflow 1. **Run a baseline backtest** on a machine with at least a few weeks of rental history: - - Check your machine's uptime history on the [Host Machines page](https://cloud.vast.ai/host/machines), then use the console SLA preview or backtester — do not rely on the dashboard reliability score alone (see [Machine reliability score vs SLA uptime](/host/sla-offers#machine-reliability-score-vs-sla-uptime)). - - Choose a target at or slightly below your current reliability for your first backtest. + - Check your machine's uptime history on the [Host Machines page](https://cloud.vast.ai/host/machines), then use the console SLA preview or backtester — do not rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). + - Choose an `r` at or slightly below the claim you plan to publish. - Use normal confidence (`p=0.6667`). - If `has_data` is `false`, widen the date range or wait for more rental history. -2. **Check `worst_day_loss`** — can you absorb that payout from a bad day? -3. **Try a higher target** (for example `r=0.99`) and see how `total_sla` changes. -4. **Run a stress test** with `reliability=0.90` at your intended target. -5. **List with headroom** — set `sla_r_claim` above `sla_r_target` on the actual offer for better client pricing than the backtester shows (the backtester uses target = claim; see [SLA Offers](/host/sla-offers)). +2. **Check `worst_day_loss`** — can you absorb that credit from a bad day? +3. **Try a higher `r`** (for example `0.99`) and see how `total_sla` changes. +4. **Run a stress test** with `reliability=0.90` at your intended claim. +5. **List with `sla_r_claim`** — set claim (and `sla_sigma_x`) on the offer; clients choose their own targets in search (see [SLA Offers](/host/sla-offers)). ## Fleet workflow @@ -315,7 +311,7 @@ done Expect roughly two seconds per machine minimum (`sleep 2` plus request time). For 50 machines, budget at least a few minutes. Run off-peak before a fleet SLA rollout. On `429`, back off per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Parallel requests are not recommended unless you implement backoff. 3. Compare `worst_day_loss` and `total_sla` across machines. -4. Apply `sla_r_claim` headroom when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). +4. Apply `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). ## When stuck @@ -327,4 +323,5 @@ Expect roughly two seconds per machine minimum (`sleep 2` plus request time). Fo - [SLA Backtest API](/api-reference/host/sla-backtest) — formal API reference for this endpoint - [SLA Offers](/host/sla-offers) — listing parameters, economics, and risk scenarios +- [SLA Coverage (clients)](/guides/instances/choosing/sla-coverage) — how renters choose targets and read `dph_total` - [API permissions](/api-reference/permissions) — `machine_read` scope required diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 5e2f1228..eb18540a 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -1,23 +1,19 @@ --- title: "SLA Offers" -description: "Offer reliability guarantees on your machines, set SLA parameters, and understand how premiums and payouts work." +description: "Offer reliability guarantees on your machines, set claim and confidence, and understand how SLA charges and payouts work." "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is reliability insurance: the client pays a small hourly SLA add-on included in **`dph_total`** (dollars per hour total in search — base compute plus SLA premium), and if uptime falls short of the agreed target, the client receives a payout from your earnings. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose coverage pay a small hourly **SLA charge** included in **`dph_total`** (dollars per hour total in search — base compute plus SLA charge), and if measured reliability falls short of their chosen target, they receive a settlement credit funded from your earnings. -This page explains how SLA offers work from the host side — what you are promising, how pricing is calculated, and what happens when uptime is good or bad. +This page explains how SLA offers work from the host side — what you set, how clients choose coverage, and what happens when uptime is good or bad. -SLA settlement is **lopsided by design**: when uptime is good, you keep the premium, but when uptime is bad, client payouts can exceed the premium you collected that day. Premiums and payouts are settled daily based on measured uptime. You can optionally preview SLA economics before listing — use the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). The console preview works on first-time listings. +SLA settlement is **asymmetric by design**: when reliability is strong relative to the client's target, you keep the SLA charge; when it falls short, client credits can exceed the charge you collected that day. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). -**Clients:** see [What your clients see](#what-your-clients-see) below for how SLA appears in search and billing. - - - -Clients pay a small hourly SLA add-on included in `dph_total` (for example, ~$0.008/hr on top of the base GPU rate). On SLA-listed on-demand offers, coverage is included automatically when the client rents — no separate host-side toggle at rent time. The published **target %** appears in search and the rent flow alongside `dph_total`. Premiums and payouts settle once per UTC calendar day; credits typically post to **Billing** within a few hours after UTC midnight (exact timing can vary). If uptime falls below the promised target, credits are applied automatically. SLA applies to on-demand rentals only — not [interruptible](/guides/instances/rental-types) instances. +**Clients:** see [SLA Coverage](/guides/instances/choosing/sla-coverage) for how SLA appears in search and billing. ## Choose your path @@ -27,7 +23,7 @@ Clients pay a small hourly SLA add-on included in `dph_total` (for example, ~$0. | Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer) | | Enable or update SLA via API | [Before you enable SLA](#before-you-enable-sla) → [API (for automation)](#api-for-automation) | | I list with CLI only (no SLA flags yet) | **Set Pricing → SLA** + **LIST** in the console, or REST `PUT /api/v0/machines/create_asks/` — SLA flags are **not** in `vastai list machine` yet | -| Monitor payouts after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | +| Monitor settlement after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | ## Before you enable SLA @@ -35,137 +31,128 @@ Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machin Before enabling SLA, finish normal listing setup: test your machine, set GPU price and offer end date, choose on-demand vs interruptible, and understand [Testing your own machine](/host/hosting-overview#testing-your-own-machine) and offer terms in [Hosting overview](/host/hosting-overview). -SLA can be enabled on a first-time listing, but you still need base listing fields (GPU price, offer end date, etc.). See [Listing an SLA offer](#listing-an-sla-offer) and [Offer End Date](/host/hosting-overview#offer-end-date). +SLA listing may require host approval and a sufficiently recent daemon. If listing fails with `sla_not_approved` or `sla_daemon_outdated`, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or update the daemon from the host setup page. **Rental types:** SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible instances on an SLA-enabled machine are not SLA-covered; on-demand contracts on the same machine are. If a client attempts to reserve or prepay an SLA-enabled offer, the request is rejected. - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. -- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview and the economics walkthrough below. Wait for rental history before trusting `worst_day_loss`. Consider wider confidence or lower targets until you have a few weeks of data. +- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting `worst_day_loss`. Consider wider confidence or a more conservative claim until you have a few weeks of data. ## How it works (plain English) -In **Host → Machines → Set Pricing → SLA** you set three knobs only: +In **Host → Machines → Set Pricing → SLA** you set host knobs only: -- **Target** — the uptime % clients see in search (your public promise). -- **Claim** — what you expect to deliver (often above Target for pricing headroom). -- **Confidence** — how tightly you price around that expectation (**High / Normal / Wide** — not an uptime %). +- **Claim** — the reliability level you believe your machine will deliver (shown to clients as `expected_reliability`). +- **Confidence** — how tightly you price around that claim (`sla_sigma_x`; lower = tighter / cheaper for clients at a given target). -The API field names and backtester aliases below are for automation. Skip them if you use the web console only. +Clients choose their own **reliability target** at search and rent time. You do **not** set the client target on the listing. -Think of an SLA offer as three linked ideas: +Think of an SLA offer as two host ideas plus one client choice: -1. **Reliability target** — the uptime level the listing is priced around (for example, 95% or 99%). -2. **Your reliability claim** — what you believe your machine will actually deliver. -3. **Your confidence** — how sure you are about that claim. Tight confidence means you stand behind a narrow range; wide confidence means a wider defensible range and clients pay a higher premium. +1. **Your reliability claim** — what you believe your machine will deliver (`sla_r_claim`). Setting this above `0` enables SLA on the offer. +2. **Your confidence** — how wide your belief is around that claim (`sla_sigma_x`). Tighter confidence → lower SLA charges for clients at a given target; wider confidence → higher charges. +3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA charge sizing use this target. Clients typically pick a target **at or below** your claim. -**Claim headroom:** Set **Claim** higher than **Target** unless you intentionally want higher client premiums. Clients pay based on the gap between claim and target; payouts still use **Target**. Example: Target 95%, Claim 99%. +When a client rents an on-demand instance on your SLA-listed offer with a chosen target: -When a client rents an on-demand instance on your SLA-listed offer, Vast measures uptime against your published target and claim percentages: +- They pay **compute** (GPU, storage, bandwidth) plus a **small hourly SLA charge** included in `dph_total`. +- Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. +- **Strong reliability relative to the client's target** → you keep the SLA charge for that day. +- **Shortfalls** → credits flow to the client from your earnings (bounded by that day's covered compute). -- They pay **compute** (GPU, storage, bandwidth) plus a **small hourly SLA add-on** included in `dph_total`. -- Each UTC calendar day, Vast measures how long the instance was online and settles the SLA. -- **Good uptime** → you keep the premium for that day. -- **Bad uptime** → you pay the client from your earnings (up to the day's compute revenue). +Over many strong days, SLA charges can offset occasional credits, but a single bad day can exceed months of collected charges — see [Risk scenarios](#risk-scenarios) and `worst_day_loss` before you commit. -Over many good-uptime days, premiums can offset occasional payouts, but a single bad day can exceed months of collected premiums — see [Risk scenarios](#risk-scenarios) and `worst_day_loss` before you commit. +### How reliability is measured -### How uptime is measured +SLA reliability is measured at the **rental contract (instance) level** using platform health signals for active on-demand contracts — not your personal SSH session or Jupyter tab. -SLA uptime is measured at the **rental contract (instance) level** using platform health signals for active on-demand contracts — not your personal SSH session or Jupyter tab. - -- **Instance fails to start** when a client rents → counts against SLA uptime for that contract. +- **Instance fails to start** when a client rents → counts against SLA reliability for that contract. - **Machine-level outage** while contracts are active → affects settlement for those contracts. -- **Brief host reboots** during active rentals may count as downtime if they exceed the platform's measurement window for that UTC day. Vast does not publish a fixed second-level threshold in host docs — treat unplanned reboots as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance) with at least 24 hours' notice when possible. +- **Brief host reboots** during active rentals may count as downtime. Vast does not publish a fixed second-level threshold in host docs — treat unplanned reboots as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance) with at least 24 hours' notice when possible. - **Scheduled maintenance** may receive credit case by case — see [Scheduled maintenance](#scheduled-maintenance). On sliced machines, SLA settles **per rental contract**. If one GPU slice fails but others remain healthy, only contracts on the affected slice are measured for downtime. +### Billing vs settlement (important) + +For SLA-covered on-demand contracts, compute billing uses the **intended daily compute** for the rental. Offline time is tracked as an outage in reliability observations. Client compensation for poor reliability flows through **SLA settlement credits**, not by silently zeroing the day's compute bill. + ## SLA parameters When you list or update a machine, set SLA fields via the host console or `PUT /api/v0/machines/create_asks/` (see [Listing an SLA offer](#listing-an-sla-offer) below). | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | -| Reliability target | `sla_r_target` | `r` | The uptime level the offer is priced around. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.95` = 95%). Exactly `1.0` is rejected. Legacy alias: `sla_reliability` (deprecated; use `sla_r_target` instead). If both are sent, `sla_r_target` takes precedence. | -| Reliability claim | `sla_r_claim` | — (backtester sets claim = target) | Your advertised belief about machine uptime. Defaults to the reliability target if omitted. Must be **≥** the target. Same bounds as target (greater than 0, at most 0.9999). | -| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the claim. Lower = more confident (cheaper for clients). Defaults to `0.5` if omitted. | +| Reliability claim | `sla_r_claim` | `r` (backtester sets claim = target = `r`) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | +| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the claim. Lower = more confident (lower SLA charges for clients at a given target). Defaults to `0.5` if omitted. | +| Max client β (optional) | `sla_max_beta` | — | Advanced term capping how path-dependent a client's timescale mix can be. Most hosts can omit this. Must be in `(0, 1)` and at least the default β derived at your claim. | -Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x`. They use different scales. Use the preset mapping table below (for example, Normal → `sla_sigma_x=0.5`, which corresponds to backtester `p=0.6667`). +**`sla_r_target` is not host-settable.** If you send `sla_r_target` or legacy `sla_reliability` on `create_asks/`, they are **ignored**. Clients supply their coverage target at search/rent time (`target_reliability`). Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x` — they use different scales. Use the mapping table on the [backtester page](/host/sla-backtester#confidence-values-p). -| Concept | Console | Listing API | Backtester | Client sees | +| Concept | Console | Listing API | Backtester | Client sees / sets | | --- | --- | --- | --- | --- | -| Reliability target | Target | `sla_r_target` | `r` | Target % (coverage level) | -| Reliability claim | Claim | `sla_r_claim` | (set equal to target in backtester) | — | -| Confidence | Confidence | `sla_sigma_x` | `p` (different scale — do not copy directly) | — | -| All-in hourly price | — | — | — | `dph_total` (dollars per hour total in search — compute plus SLA premium when enabled) | - -**Confidence is not an uptime target.** It controls how aggressively premiums are priced around your claim. - +| Reliability claim | Claim | `sla_r_claim` | `r` (claim = target in sim) | `expected_reliability` | +| Confidence | Confidence / spread | `sla_sigma_x` | `p` (different scale) | — | +| Reliability target | — (client-chosen) | — (not on asks) | `r` (same as claim in sim) | `target_reliability` in search | +| All-in hourly price | — | — | — | `dph_total` (compute plus SLA charge when enabled) | - -**Confidence in one sentence:** The **preset name** (High / Normal / Wide) controls how **tightly premiums are priced around the uptime level you claim you will deliver** (your claim), not around the published reliability target clients see in search. In the console, use the labeled presets rather than raw numbers. The ~83% figure applies to the **High** preset — it describes how often your machine's actual uptime is expected to meet or exceed your claim, not the target percentage itself. +**Confidence is not an uptime target.** It controls how aggressively SLA charges are priced around your claim. -### Machine reliability score vs SLA uptime +### Machine reliability score vs SLA reliability -The **reliability score** on the Host Machines page reflects connection and instance-start behavior (and is earnings-weighted). **SLA settlement** measures whether covered instances met your published uptime target for billing purposes. +The **reliability score** on the Host Machines page reflects connection and instance-start behavior (and is earnings-weighted). **SLA settlement** measures whether covered instances met the client's published uptime target for billing purposes. -Do not assume the dashboard score equals SLA uptime. Before choosing `sla_r_target`: +Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r_claim`: -1. Open **Host → Machines** → **Set Pricing → SLA** and review the console premium preview at candidate targets. +1. Open **Host → Machines** → **Set Pricing → SLA** and review the console SLA charge preview at candidate claims. 2. If you have rental history, run the [backtester](/host/sla-backtester) and check top-level `reliability` in the response. -3. Set **target** at or slightly below the uptime level you can sustain; use **claim above target** for competitive premiums. +3. Set **claim** at a level you can sustain; clients who pick targets below your claim see lower SLA charges. -### Confidence presets +### Confidence values -**This only changes how SLA premiums are priced — it does not change how uptime is measured or what payout you owe.** Use the **High / Normal / Wide** presets in the console UI. Only set raw `sla_sigma_x` via the API if you need a value outside those presets. +**This only changes how SLA charges are priced — it does not change how reliability is measured or what credit you owe when a client's target is missed.** Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. - -Confidence presets control **pricing weight only**, not your uptime obligation. Your obligation is set by **Target**. The statistical weights in the table below (~83% / ~67% / ~50%) describe pricing confidence — do not treat them as uptime targets. - - -| Preset | Pricing effect | `sla_sigma_x` | Risk if you miss claim | +| Guidance | Pricing effect | `sla_sigma_x` | Risk if you miss claim | | --- | --- | --- | --- | -| **High** | Tightest pricing (lowest client premiums) | `0.2` | Highest premium sensitivity | -| **Normal** (default) | Balanced | `0.5` | Moderate | -| **Wide** | Widest pricing band | `1.0` | Lowest premium sensitivity | +| Tight | Lowest client SLA charges at a given target | `0.2` | Highest charge sensitivity | +| Normal (default) | Balanced | `0.5` | Moderate | +| Wide | Highest client SLA charges at a given target | `1.0` | Lowest charge sensitivity | -Higher preset confidence (tighter spread) → lower client premiums, but less room for uptime to slip before payouts. +Higher confidence (tighter spread) → lower client SLA charges, but less room for reliability to slip before settlement credits grow. ### Validation rules Offers with invalid combinations are rejected at listing time: -- The reliability target must be greater than 0 and at most **0.9999** when enabling SLA. Set to `0` to disable SLA. -- The reliability claim must be greater than 0, at most **0.9999**, and must be **≥** the target. -- Confidence spread must be positive and at most `3.0`. +- `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.9999**. Exactly `1.0` is rejected. +- When claim is positive, `sla_sigma_x` must be positive and at most `3.0` (defaults to `0.5` if omitted). +- Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your claim. -If listing is rejected with `error: "invalid_sla_params"`, check the `msg` field against the rules above. Common causes: claim below target, `sla_sigma_x` out of range, values of exactly `1.0`, or invalid partial-update combinations. +If listing is rejected with `error: "invalid_sla_params"`, check the `msg` field against the rules above. Other SLA listing errors include `sla_not_approved` and `sla_daemon_outdated`. ### SLA and GPU slicing -SLA settlement applies per rental contract. If your machine has multiple GPU slices rented by different clients (GPU slicing — see **Min GPU** in [Hosting Overview](/host/hosting-overview)), each contract's SLA is settled independently based on the uptime experienced by that instance. +SLA settlement applies per rental contract. If your machine has multiple GPU slices rented by different clients (GPU slicing — see **Min GPU** in [Hosting Overview](/host/hosting-overview)), each contract's SLA is settled independently based on the reliability experienced by that instance. The backtester replays **machine-level** daily earnings (total compute across all active rentals on that machine). `worst_day_loss` in `summary` reflects the worst simulated day for the whole machine in the replay window — not a single GPU slice in isolation. On sliced machines, a full-machine outage can affect every concurrent SLA rental at once. Use `worst_day_loss` as your primary tail-risk metric for the machine, and sanity-check exposure against how many SLA-covered instances you typically run in parallel. Do **not** multiply `worst_day_loss` by contract count — the backtester already models machine-level compute for the replay window. -To see how many rentals are active on a machine, check the [Host Machines page](https://cloud.vast.ai/host/machines) or run `vastai show machines` and inspect the rented/active instance fields for that `machine_id`. - ### SLA on extended contracts When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. -Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. +Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. ## Listing an SLA offer @@ -174,17 +161,17 @@ Disabling SLA on the offer (setting `sla_r_target` to `0`) prevents new SLA-cove 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. -4. Set **Reliability target**, **Reliability claim**, and **Confidence** (or a preset). Set **Claim** higher than **Target** (for example, 99% claim / 95% target) unless you want higher premiums. -5. Save and confirm the SLA premium preview before listing. +4. Set **Claim** and **Confidence** (spread). Example: claim **99%** with normal confidence. +5. Save and confirm the SLA charge preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. #### Updating SLA on an already-listed machine -If the machine is already **listed** (you previously clicked **LIST** or listed via CLI/REST): +If the machine is already **listed**: -1. Open **Host → Machines → Set Pricing → SLA**, set Target, Claim, and Confidence, then click **Save**. +1. Open **Host → Machines → Set Pricing → SLA**, set Claim and Confidence, then click **Save**. 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. -3. Verify in search: `dph_total` includes the SLA add-on and `expected_reliability` matches your Target (see [Search / client-visible fields](#search--client-visible-fields)). +3. Verify in search: `dph_total` includes the SLA charge at a client's `target_reliability`, and `expected_reliability` matches your claim (see [Search / client-visible fields](#search--client-visible-fields)). In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same as pressing **LIST** or running `vastai list machine`), not a save-only draft. @@ -192,7 +179,7 @@ In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIS #### Web console SLA preview -In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA premium and payout exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA charge and payout exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. ### API (for automation) @@ -204,17 +191,11 @@ SLA listing via `vastai list machine` and `VastAI.list_machine()` is **not yet a #### Before you start -SLA listing requires the REST API today — CLI and SDK SLA flags are not yet available in published tooling. - -Before you call this endpoint, your machine must appear on **Host → Machines** with the daemon connected. This call creates or updates the **offer**, not machine registration. See [Host setup](https://cloud.vast.ai/host/setup/). - 1. Open **Account → API Keys** and create a key. See [Create API Key](/api-reference/accounts/create-api-key). -2. For listing SLA offers, enable **`machine_write`**. For backtesting first, add **`machine_read`**. For post-listing earnings, add **`billing_read`** (one key can include multiple permissions). +2. For listing SLA offers, enable **`machine_write`**. For backtesting first, add **`machine_read`**. For post-listing earnings, add **`billing_read`**. 3. Use the key as `Authorization: Bearer YOUR_API_KEY` in the `curl` examples below. See [Authentication](/api-reference/authentication). -4. To enable SLA today, use `PUT /api/v0/machines/create_asks/` or **Set Pricing → SLA** in the console. `vastai list machine` hits the same endpoint for non-SLA fields only until CLI SLA flags ship. The listing body field is `machine` (same ID as backtester `machine_id` and earnings `machid`). -5. For the full request/response schema (including `sla_r_target`, `sla_r_claim`, `sla_sigma_x`, and `invalid_sla_params`), see [List Machine](/api-reference/machines/list-machine). - -Listing or updating SLA parameters requires an API key with **`machine_write`** permission. Backtesting requires **`machine_read`**. See [API permissions](/api-reference/permissions). +4. To enable SLA today, use `PUT /api/v0/machines/create_asks/` or **Set Pricing → SLA** in the console. The listing body field is `machine` (same ID as backtester `machine_id` and earnings `machid`). +5. For the full request/response schema, see [List Machine](/api-reference/machines/list-machine). The example below **adds SLA to an offer that already has base pricing configured**. For a first-time listing, include all required base fields (`price_gpu`, `end_date`, `min_chunk`, storage/bandwidth prices as needed) — see [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). @@ -227,7 +208,6 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{ "machine": 12345, "price_gpu": 3.50, - "sla_r_target": 0.95, "sla_r_claim": 0.99, "sla_sigma_x": 0.5, "end_date": 1735689600 @@ -238,32 +218,27 @@ Set `end_date` so the offer does not stay open indefinitely — especially impor Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric payout risk. See [Offer End Date](/host/hosting-overview#offer-end-date). -Minimal example (includes recommended claim headroom): +Minimal example: ```json { "machine": 12345, "price_gpu": 3.50, "end_date": 1735689600, - "sla_r_target": 0.95, "sla_r_claim": 0.99, "sla_sigma_x": 0.5 } ``` - -Setting only `sla_r_target` defaults `sla_r_claim` to the same value, which increases client premiums. For better economics, set **claim above target** (for example, target 95%, claim 99%). - - -This creates an offer with target `0.95`, claim `0.99`, and confidence spread `0.5`. +This creates an offer with claim `0.99` and confidence spread `0.5`. Clients who search with `target_reliability` below your claim see lower SLA charges than clients who ask for coverage near your claim. -Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_target` to `0` to disable SLA on an existing listing. +Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_claim` to `0` to disable SLA on an existing listing. -Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. Read current listing fields from `vastai show machines --raw` (filter with `jq` below). See [Show Machines](/api-reference/machines/show-machines) for the documented REST response shape: +Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. Read current listing fields from `vastai show machines --raw`: ```bash -vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, sla_r_target, sla_r_claim, sla_sigma_x, price_gpu, end_date}' +vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, sla_r_claim, sla_sigma_x, price_gpu, end_date}' ``` Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. @@ -277,7 +252,7 @@ For multiple machines, loop sequentially — do not parallelize without backoff: 1. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields and required base pricing. 2. On `429`, sleep and retry with exponential backoff. -3. On `invalid_sla_params` or `machine_locked`, log the machine ID and continue or abort per your rollout policy. +3. On `invalid_sla_params`, `sla_not_approved`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. @@ -286,7 +261,7 @@ export VAST_API_KEY="YOUR_API_KEY" machines=$(vastai show machines --raw) for id in $(vastai show machines -q); do body=$(echo "$machines" | jq -c --arg id "$id" \ - '.machines[] | select((.id|tostring) == $id) | {machine: (.id|tonumber), price_gpu, end_date, min_chunk, sla_r_target: 0.95, sla_r_claim: 0.99, sla_sigma_x: 0.5}') + '.machines[] | select((.id|tostring) == $id) | {machine: (.id|tonumber), price_gpu, end_date, min_chunk, sla_r_claim: 0.99, sla_sigma_x: 0.5}') resp=$(curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer $VAST_API_KEY" \ -H "Content-Type: application/json" \ @@ -304,10 +279,10 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "sla_r_target": 0.99, "sla_r_claim": 0.995, "sla_sigma_x": 2.0}' + -d '{"machine": 12345, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` -**Disable SLA on new rentals** — set `sla_r_target` to `0` (active contracts keep their terms). +**Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). #### Common errors @@ -317,6 +292,8 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | 403 | `machine_locked` | Machine is decommissioned or migration-locked | | 400 | `invalid_args` | Machine ID not found for your account (includes other hosts' machines) | | 400 | `invalid_sla_params` | SLA parameters failed validation | +| 400 | `sla_not_approved` | Host account is not approved to create SLA asks | +| 400 | `sla_daemon_outdated` | Machine daemon build is too old for SLA listing | | 400 | `invalid_args` | Malformed or incompatible request body | **`machine_locked`:** Returned when a machine is decommissioned or migration-locked. If you are migrating hardware, finish or cancel active rentals first, remove or update the listing as needed, and contact support if the machine remains locked. Existing SLA terms on active contracts remain in force until those contracts end. @@ -344,108 +321,100 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ ## Economics walkthrough -**Setup:** You list an H100 at **$3.50/hr** GPU price with target **95%**, claim **99%**, and normal confidence (`sla_sigma_x = 0.5`). +**Setup:** You list an H100 at **$3.50/hr** GPU price with claim **99%** and normal confidence (`sla_sigma_x = 0.5`). A client searches with **target 95%**. | Item | Amount | | --- | --- | | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr GPU only — simplified) | -| SLA premium (client pays) | ~**$0.008/hr** (~$0.20/day at 24 hr) | +| SLA charge (client pays) | ~**$0.008/hr** (~$0.20/day at 24 hr) | -SLA payouts are capped at that UTC day's total billable earnings — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat `worst_day_loss` from the [SLA backtester](/host/sla-backtester) as the authoritative tail-risk figure before you list. +SLA credits are capped relative to that UTC day's covered compute — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat `worst_day_loss` from the [SLA backtester](/host/sla-backtester) as the authoritative tail-risk figure before you list. -Premium sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst single-day payout exposure (`worst_day_loss`), not exact client premiums. For authoritative client-visible premiums, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers — not backtester `total_sla` when claim exceeds target. +SLA charge sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst single-day credit exposure (`worst_day_loss`), not exact client SLA charges. For authoritative client-visible charges, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers at a chosen `target_reliability` — not backtester `total_sla` when clients will rent below your claim. -The economics above assume **claim above target** (headroom): claim (99%) is above target (95%), so clients see lower premiums than if both matched. The [backtester](/host/sla-backtester) cannot simulate claim headroom — it sets claim equal to target — so its simulated premiums will be higher. Use `worst_day_loss` from the backtester as your worst single-day payout reference, then verify visible premiums in **Set Pricing → SLA** (or `dph_total` in search) before listing with claim above target. +The backtester sets claim equal to target (`r`), which is a **conservative** what-if (as if every client targeted your claim). Live clients who choose targets **below** your claim usually see lower SLA charges than the backtester's simulated charges. Use `worst_day_loss` from the backtester as your worst single-day credit reference, then verify visible charges in **Set Pricing → SLA** (or `dph_total` in search) before listing. -This premium is what a client searching for 95% reliability would see added to the total hourly price in search results (`dph_total` — visible in the console SLA preview or [Search Offers](/api-reference/search/search-offers) results). - ### Search / client-visible fields When SLA is enabled on an offer, clients see: -- **`dph_total`** — total $/hour including the SLA premium (authoritative for client-visible all-in pricing). -- **`expected_reliability`** — the advertised SLA target (maps to your `sla_r_target`). -- **`reliability` / `reliability2`** — historical machine reliability scores, **not** your SLA target. +- **`dph_total`** — total $/hour including the SLA charge at their `target_reliability` (authoritative for client-visible all-in pricing). +- **`expected_reliability`** — your advertised claim (maps to `sla_r_claim`). +- **`reliability` / `reliability2`** — historical machine reliability scores, **not** your SLA claim. -**Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the SLA target. The published SLA target appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, post-filter on `expected_reliability > 0` (or your minimum target); do not use the `reliability` filter as an SLA selector. +**Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the SLA claim. The published SLA claim appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, use `has_sla=true` or filter on `expected_reliability > 0`; do not use the `reliability` filter as an SLA selector. Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand): ```bash -vastai search offers 'machine_id=12345 verified=any' --raw \ +vastai search offers 'machine_id=12345 verified=any has_sla=true target_reliability=0.95' --raw \ | jq '[.offers[] | select(.is_bid == false) | {id, num_gpus, dph_total, expected_reliability, reliability}]' ``` -Premium sizing uses internal SLA math — use the console preview or `dph_total` above, not backtester `total_sla`, when claim exceeds target. - -### If you meet your claim +### If reliability is strong relative to the client's target -In the **You net** column, values follow host earnings sign conventions: positive means premium you kept; negative means payout you owed the client. +In the **You net** column, values follow host earnings sign conventions: positive means SLA charge you kept; negative means credit you owed the client. -| Measured uptime (simplified) | You net (per day) | +| Measured reliability (simplified) | You net (per day) | | --- | --- | -| ~100% (excellent day) | +$0.20 (keep premium) | -| ~99% (good day) | +$0.17 (keep premium) | +| ~100% (excellent day) | +$0.20 (keep SLA charge) | +| ~99% (good day) | +$0.17 (keep most of the SLA charge) | -You keep most or all of the premium. +You keep most or all of the SLA charge. -### What if measured uptime is between my target and my claim? +### What if measured reliability is between the client's target and my claim? -Example: you publish **target 95%**, claim **99%**, and measured uptime is **~97%**. +Example: you publish **claim 99%**, the client chose **target 95%**, and measured reliability is **~97%**. -- **Payouts** are evaluated against your published **target** (95%), not your claim. -- Because 97% is above 95%, you typically **owe no SLA payout** for that day. -- **Premiums** are priced from your **claim** (99%) and confidence — a higher claim generally means lower client premiums. +- **Credits** are evaluated against the client's **target** (95%), not your claim. +- Because 97% is above 95%, you typically **owe no SLA credit** for that day. +- **SLA charges** are priced from your **claim**, confidence, and the client's target — a higher claim relative to the target generally means lower client charges. -**Claim** is mainly a pricing knob; **target** is what clients see and what drives payout eligibility. +**Claim** is your belief/pricing knob; the client's **target** is what drives payout eligibility. -### If you miss the target +### If the client's target is missed -Payouts scale relative to the day's compute revenue, not the premium collected. A single bad day at your target boundary can cost as much as 200+ days of collected premiums. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. +Credits scale relative to the day's compute, not only the SLA charge collected. A single bad day near the client's target boundary can cost as much as 200+ days of collected SLA charges. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. - -Visible client premiums are lower than backtester output when `sla_r_claim` is above `sla_r_target`. Use `worst_day_loss` as your worst single-day payout reference. The table below illustrates payout at the target boundary only. - +These scenarios show settlement when reliability **drops to or below** a 95% client target — they are boundary illustrations, not typical strong days: -These scenarios show settlement when uptime **drops to or below** the target — they are boundary illustrations, not typical good-uptime days. Payouts for brief outages may be **smaller than the worst-case table** shown below; exact settlement depends on measured uptime for the UTC day and active contract terms: - -| Measured uptime (simplified) | You net (per day) | +| Measured reliability (simplified) | You net (per day) | | --- | --- | -| At target (~95%) | −$42 (payout you owe) | -| Well below target (~90% or less) | −$84 (full compute refund owed) | +| At target (~95%) | −$42 (credit you owe) | +| Well below target (~90% or less) | −$84 (large credit owed) | -To put the asymmetry in perspective: at ~$0.20/day in premiums, it takes roughly 210 good days to accumulate the $42 you could lose on a single day at the target boundary. The premium is a small fraction of daily compute, while the payout scales against total daily compute revenue. +To put the asymmetry in perspective: at ~$0.20/day in SLA charges, it takes roughly 210 strong days to accumulate the $42 you could lose on a single day at the target boundary. The SLA charge is a small fraction of daily compute, while credits scale against total daily compute. -On a severe outage day, the client is made whole on compute charges for that day. You do not collect the premium for that day either — the client is not charged a premium on top of compute charges for periods when the instance was down. Your maximum SLA loss on any single settlement day is capped at that day's total billable earnings (GPU, storage, and bandwidth). +Your maximum SLA loss on any single settlement day is bounded by that day's covered compute (GPU, storage, and bandwidth). ## Risk scenarios -### You claim 99% but deliver 99.5% +### You claim 99% and deliver 99.5% -You outperform your claim. Clients pay small premiums; payouts are rare. You net positive on SLA over time. +You outperform your claim. Clients who chose targets at or below 99% pay small SLA charges; credits are rare. You net positive on SLA over time. ### You claim 99% but have an offline day -Clients receive payouts tied to how far measured uptime falls below the target. Extended outages can approach a full-day compute refund. Your reliability score and verification status may also be affected separately from SLA settlement. +Clients receive credits tied to how far measured reliability falls below **their** target. Extended outages can approach a full-day compute credit. Your reliability score and verification status may also be affected separately from SLA settlement. -### You set target equal to claim (for example, both 95%) +### Clients target near your claim -Premiums are **much higher** because you are not offering any headroom — you are not setting **claim above target**. Clients only buy this when they need coverage exactly at your stated level. Prefer setting **claim above target** (for example, claim 99%, target 95%) for competitive premiums. +SLA charges are **much higher** when the client's target sits near your claim (little headroom). Prefer a claim you can sustain above the targets clients actually choose. ### You widen confidence (`sla_sigma_x` → 1.0) -Clients pay more because you admit greater uncertainty. Use this if your uptime history is volatile or the machine is new. +Clients pay more because you admit greater uncertainty. Use this if your reliability history is volatile or the machine is new. ### Scheduled maintenance -Maintenance windows scheduled through [`vastai schedule maint`](/host/cli/schedule-maint) may be credited back toward uptime, reducing SLA penalties for planned downtime. Unplanned outages count fully toward SLA settlement. +Maintenance windows scheduled through [`vastai schedule maint`](/host/cli/schedule-maint) may be credited back toward reliability, reducing SLA penalties for planned downtime. Unplanned outages count fully toward SLA settlement. -Planned maintenance credit is not guaranteed. The platform evaluates advance notice (generally at least 24 hours recommended) and maintenance duration when determining credit eligibility. **Treat any scheduled downtime as a potential SLA payout event when modeling risk.** Contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or email [contact@vast.ai](mailto:contact@vast.ai) before extended maintenance on an SLA-listed machine to confirm credit eligibility. +Planned maintenance credit is not guaranteed. The platform evaluates advance notice (generally at least 24 hours recommended) and maintenance duration when determining credit eligibility. **Treat any scheduled downtime as a potential SLA credit event when modeling risk.** Contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or email [contact@vast.ai](mailto:contact@vast.ai) before extended maintenance on an SLA-listed machine to confirm credit eligibility. ## Preview earnings before listing @@ -454,26 +423,27 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m ## When things go wrong -- **Listing rejected (`invalid_sla_params`)** — Re-check target, claim, and `sla_sigma_x` against [validation rules](#validation-rules). -- **Unexpected payout** — Review uptime; re-run the backtester with a low `reliability` stress value (for example `0.01`). -- **Severe outage** — Disable SLA on new contracts: open **Host → Machines** → **Set Pricing → SLA**, set target to `0` (or use API `sla_r_target=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. +- **Listing rejected (`invalid_sla_params`)** — Re-check claim and `sla_sigma_x` against [validation rules](#validation-rules). +- **`sla_not_approved` / `sla_daemon_outdated`** — Contact support or update the daemon from the host setup page. +- **Unexpected credit** — Review reliability; re-run the backtester with a low `reliability` stress value (for example `0.01`). +- **Severe outage** — Disable SLA on new contracts: open **Host → Machines** → **Set Pricing → SLA**, set claim to `0` (or use API `sla_r_claim=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. ## Monitoring SLA after listing -After you enable SLA, premiums and payouts settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). +After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). ### Console (recommended for day-to-day checks) 1. Go to **Host → Billing** (or **Earnings** / **Reports**). 2. Set the date range to include the UTC day you want to review. 3. Filter by machine ID if available. -4. Look for **SLA** entries in the earnings breakdown — positive amounts are premiums you kept; negative amounts are payouts you owed the client. +4. Look for **SLA** entries in the earnings breakdown — positive amounts are SLA charges you kept; negative amounts are credits you owed the client. 5. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. **If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). -SLA daily settlement (premium kept / payout owed) does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. +SLA daily settlement (SLA charge kept / credit owed) does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. ### CLI @@ -499,14 +469,7 @@ vastai show earnings --machine_id --start_date $(date -u -d 'yesterday' +%F | jq '.per_machine[] | select(.machine_id == or .machine_id == "") | {machine_id, sla_earn}' ``` -**Linux (GNU date) — seven-day window (do not compare directly to single-day `worst_day_loss`):** - -```bash -vastai show earnings --machine_id --start_date $(date -u -d '7 days ago' +%F) --end_date $(date -u +%F) --raw \ - | jq '.per_machine[] | select(.machine_id == or .machine_id == "") | {machine_id, sla_earn}' -``` - -Positive `sla_earn` = net SLA premium you kept that period; negative = net payout you owe. Weekly aggregates are window totals, not daily series — use a one-day range above for day-level checks. +Positive `sla_earn` = net SLA charge you kept that period; negative = net credit you owe. Weekly aggregates are window totals, not daily series — use a one-day range above for day-level checks. ### API (automation) @@ -522,17 +485,15 @@ Positive `sla_earn` = net SLA premium you kept that period; negative = net payou | List or update SLA on an offer | `machine_write` | | Post-listing SLA earnings | `billing_read` | -For API automation only — console users can stop after the Console subsection above. +`GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key. See [`show earnings`](/api-reference/billing/show-earnings). -`GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key (separate from `machine_read` used for the backtester). See [`show earnings`](/api-reference/billing/show-earnings). - -This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll no faster than about one request every two seconds per IP (`threshold=2.0`); back off on HTTP 429. For day-level per-machine reconciliation at scale, prefer console billing reports over high-frequency API polling. +This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll no faster than about one request every two seconds per IP (`threshold=2.0`); back off on HTTP 429. -When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. Do not assume `summary.total_sla` is machine-scoped when `machid` is set — prefer `per_machine[].sla_earn`. +When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` (UTC day indices). The CLI flags `--start_date` and `--end_date` map internally to those fields — they are not separate REST query parameter names on `machine-earnings/`. +- **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` (UTC day indices). - **Fleet snapshot:** one request without `machid` returns all machines in `per_machine[]` for the window: ```bash @@ -540,8 +501,6 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?last_days=1" \ | jq '.per_machine[] | {machine_id, sla_earn}' ``` - -Poll no faster than about one request every two seconds. Prefer console billing exports for month-end reconciliation. **Machine-scoped one-day total:** @@ -556,27 +515,25 @@ Do **not** compare `last_days=7` totals to single-day `worst_day_loss` from the **Sign convention** (same as backtester `sla` / `historical_sla`): -| Field | Good day (meet target) | Bad day (miss target) | +| Field | Strong day (meet client target) | Weak day (miss client target) | | --- | --- | --- | -| `per_machine[].sla_earn` | Positive (premium kept) | Negative (payout you owe) | -| Fleet `per_day[].sla_earn` | Positive (premium kept) | Negative (payout you owe) | +| `per_machine[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | +| Fleet `per_day[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | - `{user_id}` — Your account ID (from **Account → Profile** in the console, or `vastai show user`). -- `sday` / `eday` — UTC day indices (days since 1970-01-01). Prefer `?last_days=N` on the API if you do not want to compute indices manually. - Settlement is evaluated on UTC day boundaries. Rows typically update within a few hours after UTC midnight. -The backtester's `historical_sla` replays past settlement and is not a live billing feed. For day-level per-machine reconciliation, use **Host → Billing**; use `last_days=1` API polling only when you need automation. - ## Tips for competitive SLA offers -- **Set claim above target.** A claim of 99% with a target of 95% produces a much lower premium than matching them both at 95%. -- **Tighten confidence only when earned.** Use high confidence (`sla_sigma_x ≈ 0.2`) after you have a strong uptime track record on that machine. -- **Keep the machine online during active contracts.** SLA payouts and verification are separate systems, but both respond to downtime. -- **SLA applies to on-demand rentals only.** It does not apply to interruptible/bid instances or reserved/prepay rentals. If a client attempts to reserve or prepay an SLA-enabled offer, the request is rejected. When a client starts an on-demand rental on an SLA-enabled offer, SLA terms lock for that rental contract and do not change if you later edit the offer. -- **Use the [SLA backtester](/host/sla-backtester) (API-only)** to preview how different targets and confidence levels would have affected past earnings. +- **Claim a level you can sustain.** Clients who choose targets below your claim see lower SLA charges and still get meaningful coverage. +- **Tighten confidence only when earned.** Use a tighter spread (`sla_sigma_x ≈ 0.2`) after you have a strong reliability track record on that machine. +- **Keep the machine online during active contracts.** SLA credits and verification are separate systems, but both respond to downtime. +- **SLA applies to on-demand rentals only.** It does not apply to interruptible/bid instances or reserved/prepay rentals. When a client starts an on-demand rental on an SLA-enabled offer, SLA terms lock for that rental contract and do not change if you later edit the offer. +- **Use the [SLA backtester](/host/sla-backtester) (API-only)** to preview how different claims and confidence levels would have affected past earnings. ## Related documentation +- [SLA Coverage (clients)](/guides/instances/choosing/sla-coverage) — how renters find and evaluate SLA offers - [SLA Earnings Backtester](/host/sla-backtester) — preview SLA economics on historical earnings - [Hosting Overview](/host/hosting-overview) — offers, rental contracts, and listing basics - [Understanding Verification](/host/understanding-verification) — platform verification (separate from SLA, but related to trust) diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index adf465d0..07ea34e8 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA parameters (`--sla_r_target`, `--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). +SLA parameters (`--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). For SLA listing via REST, see [SLA Offers — API (for automation)](/host/sla-offers#api-for-automation). Volume and duration options (`-v`, `-z`, `-l`) are available in the CLI today. REST callers should confirm supported `create_asks/` body fields in the [List Machine API reference](/api-reference/machines/list-machine) before sending them — some CLI-only fields may not yet appear in the published OpenAPI schema. diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index ce4562ff..5258f72d 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA parameters (`sla_r_target`, `sla_r_claim`, `sla_sigma_x`) are **not yet available** in the published Python SDK. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). +SLA parameters (`sla_r_claim`, `sla_sigma_x`) are **not yet available** in the published Python SDK. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). Volume and duration listing parameters (`vol_size`, `vol_price`, `duration`, `price_min_bid`) require the CLI or REST API today — they are not in the SDK signature below. From 007833c846f912f7968ff298db8525b642c7db8d Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 13:46:51 -0700 Subject: [PATCH 017/250] docs(sla): address doc-review consensus (cycle 1) Clarify SLA opt-in and on-demand scope for clients, align search/instances OpenAPI, and remove internal release notes from the publishable tree. Co-authored-by: Cursor --- api-reference/openapi.yaml | 88 ++++++++++--- api-reference/openapi/yaml/search_offers.yaml | 24 +++- .../openapi/yaml/show_instances.yaml | 33 ++++- cli/reference/search-offers.mdx | 2 +- .../HOST-2752-SLA-API-Documentation.md | 37 ------ guides/instances/choosing/find-and-rent.mdx | 6 +- guides/instances/choosing/sla-coverage.mdx | 118 ++++++++++++------ host/hosting-overview.mdx | 4 +- host/sla-offers.mdx | 23 +++- snippets/host/cli/list-machine.mdx | 4 +- 10 files changed, 233 insertions(+), 106 deletions(-) delete mode 100644 docs/release-notes/HOST-2752-SLA-API-Documentation.md diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 6fc62732..54e3bed5 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6616,8 +6616,31 @@ paths: - RTX_4090 reliability: type: object - description: 'Machine reliability score (0-1). Example: {"gte": - 0.99}' + description: 'Historical machine reliability score (0-1), not the + host SLA claim. Example: {"gte": 0.99}' + target_reliability: + type: object + description: 'Client SLA coverage target (0-1). When set, search + prices include the SLA charge in dph_total + + and returns search.slaPremiumPerHour. Example: {"eq": 0.95} + + ' + has_sla: + type: object + description: 'Restrict to offers with SLA enabled (true) or without + (false). Example: {"eq": true} + + ' + properties: + eq: + type: boolean + expected_reliability: + type: object + description: 'Host SLA claim on the offer (0-1). Example: {"gte": + 0.99} + + ' num_gpus: type: object description: 'Number of GPUs. Example: {"gte": 4} or {"in": [1, @@ -6916,7 +6939,13 @@ paths: vram_costperhour: 0.009876 webpage: null vms_enabled: false - expected_reliability: 0.5 + expected_reliability: 0.99 + search: + gpuCostPerHour: 0.123456 + diskHour: 0.123456 + totalHour: 0.234567 + discountTotalHour: 0.01 + discountedTotalPerHour: 0.224567 is_vm_deverified: false resource_type: gpu cluster_id: null @@ -6932,12 +6961,6 @@ paths: discount_rate: 0.05 discounted_hourly: 0.01 discounted_dph_total: 0.224567 - search: - gpuCostPerHour: 0.123456 - diskHour: 0.123456 - totalHour: 0.234567 - discountTotalHour: 0.01 - discountedTotalPerHour: 0.224567 instance: gpuCostPerHour: 0.01 diskHour: 0.02 @@ -8040,8 +8063,14 @@ paths: `gt`, `gte`, `lt`, `lte`, `in`, `notin`. Filterable columns: `actual_status`, `gpu_name`, `verification`, `id`, `label`, - and other columns stored directly on the contract record. Computed fields - (e.g. `dph_total`, `num_gpus`) are not filterable and return 400. + and other columns stored directly on the contract record + + (including `sla_r_claim` and `sla_r_target` / `target_reliability` when + present). Computed fields (e.g. `dph_total`, `num_gpus`, `has_sla`) are + not filterable and return 400. + + To find SLA-covered instances, filter client-side on `target_reliability + > 0` or use `select_filters` on `sla_r_target` if supported for your key. ' schema: @@ -8349,7 +8378,36 @@ paths: dph_total: type: number format: float + description: Total $/hour including storage (and SLA charge + when applicable). example: 0.8021 + target_reliability: + type: number + format: float + nullable: true + description: Client SLA coverage target locked at rent time. + Null or 0 when the rental has no SLA. + example: 0.95 + sla_r_claim: + type: number + format: float + nullable: true + description: Host reliability claim for this SLA contract. + example: 0.99 + sla_sigma_x: + type: number + format: float + nullable: true + description: Host confidence spread for this SLA contract. + example: 0.5 + search: + type: object + example: + gpuCostPerHour: 0.8 + diskHour: 0.0021 + totalHour: 0.8021 + discountTotalHour: 0 + discountedTotalPerHour: 0.8013 dlperf: type: - number @@ -8401,14 +8459,6 @@ paths: - string - 'null' example: null - search: - type: object - example: - gpuCostPerHour: 0.8 - diskHour: 0.0021 - totalHour: 0.8021 - discountTotalHour: 0 - discountedTotalPerHour: 0.8013 instance: type: object example: diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index fbf7ecdb..93a834dc 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -88,7 +88,23 @@ paths: example: ["RTX_3090", "RTX_4090"] reliability: type: object - description: 'Machine reliability score (0-1). Example: {"gte": 0.99}' + description: 'Historical machine reliability score (0-1), not the host SLA claim. Example: {"gte": 0.99}' + target_reliability: + type: object + description: | + Client SLA coverage target (0-1). When set, search prices include the SLA charge in dph_total + and returns search.slaPremiumPerHour. Example: {"eq": 0.95} + has_sla: + type: object + description: | + Restrict to offers with SLA enabled (true) or without (false). Example: {"eq": true} + properties: + eq: + type: boolean + expected_reliability: + type: object + description: | + Host SLA claim on the offer (0-1). Example: {"gte": 0.99} num_gpus: type: object description: 'Number of GPUs. Example: {"gte": 4} or {"in": [1, 2, 4, 8]}' @@ -362,7 +378,11 @@ paths: vram_costperhour: 0.009876 webpage: null vms_enabled: false - expected_reliability: 0.5 + expected_reliability: 0.99 + search: + slaPremiumPerHour: 0.008 + gpuCostPerHour: 3.5 + totalHour: 3.508 is_vm_deverified: false resource_type: "gpu" cluster_id: null diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index fdc28df8..d280c1d1 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -54,7 +54,9 @@ paths: required: false description: | JSON object of column filters. Supported operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `notin`. - Filterable columns: `actual_status`, `gpu_name`, `verification`, `id`, `label`, and other columns stored directly on the contract record. Computed fields (e.g. `dph_total`, `num_gpus`) are not filterable and return 400. + Filterable columns: `actual_status`, `gpu_name`, `verification`, `id`, `label`, and other columns stored directly on the contract record + (including `sla_r_claim` and `sla_r_target` / `target_reliability` when present). Computed fields (e.g. `dph_total`, `num_gpus`, `has_sla`) are not filterable and return 400. + To find SLA-covered instances, filter client-side on `target_reliability > 0` or use `select_filters` on `sla_r_target` if supported for your key. schema: type: string default: '{}' @@ -332,7 +334,36 @@ paths: dph_total: type: number format: float + description: Total $/hour including storage (and SLA charge when applicable). example: 0.8021 + target_reliability: + type: number + format: float + nullable: true + description: Client SLA coverage target locked at rent time. Null or 0 when the rental has no SLA. + example: 0.95 + sla_r_claim: + type: number + format: float + nullable: true + description: Host reliability claim for this SLA contract. + example: 0.99 + sla_sigma_x: + type: number + format: float + nullable: true + description: Host confidence spread for this SLA contract. + example: 0.5 + search: + type: object + description: Price breakdown for search-context costs (may include slaPremiumPerHour). + additionalProperties: true + properties: + slaPremiumPerHour: + type: number + format: float + description: SLA charge rate in $/hour (API field name). + example: 0.008 dlperf: type: number nullable: true diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 4d24bacd..b31331b4 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -148,7 +148,7 @@ vastai search offers 'cpu_arch=arm64' | `pci_gen` | float | PCIE generation | | `pcie_bw` | float | PCIE bandwidth (CPU to GPU) | | `reliability` | float | machine reliability score (see FAQ for explanation) | -| `expected_reliability` | float | host SLA claim (`sla_r_claim`); `0` when SLA is off | +| `expected_reliability` | float | host’s advertised SLA reliability claim on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | | `target_reliability` | float | your desired SLA coverage level; drives SLA charge in `dph_total` | | `rentable` | bool | is the instance currently rentable | diff --git a/docs/release-notes/HOST-2752-SLA-API-Documentation.md b/docs/release-notes/HOST-2752-SLA-API-Documentation.md deleted file mode 100644 index 23ef8f96..00000000 --- a/docs/release-notes/HOST-2752-SLA-API-Documentation.md +++ /dev/null @@ -1,37 +0,0 @@ -# HOST-2752: Host & client SLA documentation - -**Branch:** `HOST-2752-SLA-API-Documentation` -**Base:** `origin/main` -**Scope:** User-facing SLA docs aligned to v5 ask/search model and compliance wording. - -## Summary - -Documents SLA for hosts and clients under the current design: hosts publish a **claim** and **confidence** (`sla_r_claim`, `sla_sigma_x`); clients choose **target** at search/rent (`target_reliability`). User-facing copy uses **SLA charge** (not premium) and avoids insurance/betting language. - -## Details - -### Guides - -| Page | Path | Audience | -| --- | --- | --- | -| SLA Offers | `/host/sla-offers` | Hosts — claim/confidence listing, economics, monitoring | -| SLA Earnings Backtester | `/host/sla-backtester` | Hosts — historical replay (`r` = claim=target in sim) | -| SLA Coverage | `/guides/instances/choosing/sla-coverage` | Clients — search filters, charges, credits | - -### Model corrections vs earlier drafts - -- `sla_r_target` is **not** host-settable on asks (ignored if sent). -- SLA activates on `sla_r_claim > 0`; disable with `sla_r_claim = 0`. -- Optional `sla_max_beta` documented for advanced hosts. -- Backtester `beta` is derived from `r` for non-admins. -- Billing note: intended compute billed; compensation via settlement credits. - -### OpenAPI / nav - -- `list_machine.yaml`, `show_machines.yaml`, `sla_backtest.yaml`, `show_earnings.yaml` updated; `openapi.yaml` regenerated. -- `docs.json` adds client SLA Coverage under Find & rent. -- Search CLI docs list `has_sla`, `expected_reliability`, `target_reliability`. - -## Compliance wording - -Forbidden in user docs: insurance, premium (prefer **SLA charge**), betting, gambling, bet. API field names such as `slaPremiumPerHour` are documented as the SLA charge rate without using “premium” as prose. diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 235e1e98..08c75f4e 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -54,9 +54,9 @@ All stats shown are the portion of the total machine rented. - Disk speed: The speed of the local storage on the machine in MB/s - Total available disk: The maximum amount of disk space available - DLPERF score: A custom deep learning performance score -- Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. +- Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. On SLA listings, the breakdown also shows an **SLA charge** line — see [SLA Coverage](/guides/instances/choosing/sla-coverage). - Max Duration: The maximum length of a rental contract on this machine -- Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. +- Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host SLA claim. Rental Option: RENT Button ## Instance Disk Size @@ -71,7 +71,7 @@ When the instance is created, the disk size is set and cannot be modified. It is ## Instance Configuration -Vast.ai provides out Linux docker instances. One key step during setup is specifying what Linux docker image to load. You can also specify Docker run commands, an on-start script that executes bash commands on instance start and a launch mode to connect to the instance. +Vast.ai provides Linux Docker instances. One key step during setup is specifying what Linux docker image to load. You can also specify Docker run commands, an on-start script that executes bash commands on instance start and a launch mode to connect to the instance. The instance configuration menu is accessible in the upper left of the create instance interface. The current template is always displayed in the upper left. Click on the "Change Template" button to bring up the template config menu that allows selecting and editing templates. For a quick overview, see [Choosing a Template](/guides/instances/choosing/templates). For detailed template creation and Docker configuration, see the main [Templates documentation](/guides/templates/introduction) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 886c5f1b..0b01823b 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,43 +4,49 @@ description: "Rent GPU instances with reliability guarantees. Learn how SLA char "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — a reliability guarantee bundled with your on-demand rental. You choose a reliability **target** when you search, pay a small hourly **SLA charge** on top of compute, and if measured reliability falls short of that target, you receive settlement credits. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — a reliability guarantee you can add to an **on-demand** rental. You choose a reliability **target** when you search, pay a small hourly **SLA charge** on top of compute, and if measured reliability falls short of that target, you receive settlement credits. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. + +**SLA is opt-in.** Coverage applies only when you set a reliability target in Search before you rent (console or `target_reliability` in API/CLI). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. + + + +SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). + + You do not post escrow or collateral for SLA. You pay the SLA charge while the instance runs. Settlement happens automatically on a daily cadence. ## What SLA protects -SLA is a **contractual, per-rental** reliability guarantee with automatic daily settlement. It is **not** the same as [verification](/host/understanding-verification) or the **reliability score** shown on offer cards — those are platform trust signals. +SLA is a **contractual, per-rental** reliability guarantee with automatic daily settlement. It is **not** the same as verification or the **reliability score** on offer cards — those are platform trust signals (see [Machine Tiers](/guides/instances/choosing/find-and-rent#machine-tiers)). For SLA-covered on-demand contracts: -- Compute is billed for the **intended** rental day (offline time is tracked as an outage in reliability measurements). -- **Settlement credits** compensate you when measured reliability falls short of your chosen target. -- On strong-reliability days, you simply pay the SLA charge with no credit. +- You are charged for **compute and the SLA charge** for the rental day, including periods when the instance is unavailable. +- Offline time is tracked as an outage in reliability measurements. +- If you qualify for compensation, a **settlement credit** posts after daily settlement (UTC) — typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. SLA is most useful for **long-running production workloads** where unexpected downtime has a real cost beyond the hourly rate. ## How pricing works -Total hourly cost with SLA: +Total hourly cost with SLA (`dph_total` = all-in dollars per hour in search): ``` total ≈ GPU + storage + bandwidth + SLA charge ``` -The SLA charge depends on: - -| Factor | Where it comes from | Effect | -| --- | --- | --- | -| Your reliability target | Your search filter (`target_reliability`) | Higher target → higher SLA charge | -| Host reliability claim | `expected_reliability` on the offer | Higher claim → lower SLA charge (at a given target) | -| Host confidence | Derived from `sla_sigma_x` on the offer | Tighter confidence → lower SLA charge | +| Factor | What it means for you | +| --- | --- | +| Your reliability target | Higher target → higher SLA charge | +| Host SLA claim | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher claim → lower SLA charge at a given target | +| Host confidence | Host pricing setting that affects SLA charge size (tighter = lower charge at a given target) | -**Rule of thumb:** pick a target **at or below** the host's claim for the best value. If you ask for 99% coverage on a host who only claims 95%, the SLA charge is much higher than asking for 95% on a host who claims 99%. +**Rule of thumb:** pick a target **at or below** the host's claim for the best value. Asking for 99% coverage on a host who only claims 95% costs much more than asking for 95% on a host who claims 99%. ### Example: H100 at $3.50/hr GPU @@ -50,15 +56,20 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 | --- | --- | | GPU compute | $3.50/hr | | SLA charge | ~$0.008/hr | -| **Total** | ~$3.51/hr | - -The SLA charge is a small fraction of compute when the host's claim comfortably exceeds your target. +| **Total (`dph_total`)** | ~$3.51/hr | ## Finding SLA offers -### Search filters +### In the web console + +1. Open [Search](https://cloud.vast.ai/create/). +2. Set your **reliability target** in Search filters (and optionally filter to SLA-enabled offers). Exact control labels match the UI. +3. Confirm the price breakdown shows an **SLA charge** line and that **total $/hr** includes it before you rent. +4. The target you set here is what locks in at rent time. -Use these filters in [Search](https://cloud.vast.ai/create/) or the [search offers API](/api-reference/search/search-offers): +CLI and API examples below use the same filters. + +### Search filters | Filter | Meaning | Example | | --- | --- | --- | @@ -66,6 +77,10 @@ Use these filters in [Search](https://cloud.vast.ai/create/) or the [search offe | `has_sla` | Restrict to offers with (or without) SLA enabled. | `has_sla=true` | | `expected_reliability` | Filter by the host's advertised claim. | `expected_reliability>=0.99` | + +**API integrators:** `reliability` is the historical machine score, not the host’s SLA claim. Use `has_sla=true` and/or `expected_reliability` to find SLA listings. + + **CLI examples:** ```bash @@ -80,37 +95,45 @@ When you set `target_reliability`, search results include: | Response field | Meaning | | --- | --- | -| `search.slaPremiumPerHour` | SLA charge for this offer at your target (API field name; this is the SLA charge rate) | +| `search.slaPremiumPerHour` | SLA charge for this offer at your target (API field name) | | `dph_total` | Total hourly cost **including** the SLA charge | | `expected_reliability` | Host's reliability claim | -Hover the price breakdown on an offer card to see GPU, storage, bandwidth, and the SLA charge separately. +Hover over the price breakdown on an offer card to see GPU, storage, bandwidth, and the SLA charge separately. -When you search with an SLA target, **reserved-instance discounts are not applied** to the displayed total. SLA charges are never discounted. +When you search with an SLA target, reserved-instance discounts may not apply to the displayed total. Confirm in the console price breakdown. SLA charges are never discounted. ### Comparing offers -Two offers at the same GPU price can have very different SLA costs: - | Offer | GPU/hr | Host claim | Your target | SLA charge/hr | | --- | --- | --- | --- | --- | | A | $3.50 | 99% | 95% | ~$0.008 | | B | $3.50 | 95% | 95% | much higher | -Offer A is dramatically cheaper on SLA because the host claims more headroom above your target. Always compare **`dph_total`**, not just GPU price, when SLA matters. +Always compare **`dph_total`**, not just GPU price, when SLA matters. Search ranking also accounts for SLA cost. + +### API automation -Search ranking also accounts for SLA cost — offers with expensive coverage at your target rank lower per dollar of performance. +1. **Search** with `target_reliability` set (and optionally `has_sla=true`, `expected_reliability>=…`) in the same request you use to pick an offer. +2. **Rent** the offer ID from that search response so pricing and contract terms match `dph_total`. +3. **Verify** on the new instance: `target_reliability` and related SLA fields in show-instances output. + +`target_reliability` is a **search-time** parameter; create-instance does not accept separate SLA fields — terms come from the search context used before rent. ## What happens after you rent -When you rent an SLA-backed offer: +When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target, the host's claim, and confidence spread are fixed for that rental. +1. **Contract terms lock in** — your reliability target, the host's claim, and confidence are fixed for that rental. 2. **Daily billing** — you pay compute plus the SLA charge each day. 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. -4. **Credits appear in billing** — positive credits improve your balance; strong days mean you paid the SLA charge with no credit. +4. **Credits appear in billing** — settlement credits improve your balance; strong days mean you paid the SLA charge with no credit. + +### What you pay during an outage + +You are still charged for **compute and the SLA charge** for the rental day while the instance is unavailable. If you qualify for compensation, a **settlement credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. ### How reliability is measured @@ -126,13 +149,15 @@ Scheduled maintenance with adequate notice may be credited toward reliability. U Using the H100 example ($84/day compute, ~$0.20/day SLA charge, target 95%, host claim 99%): -| Day's measured reliability (simplified) | What you pay | What you receive | Your net vs no-SLA baseline | +| Day's measured reliability (simplified) | What you pay | What you receive | Extra cost vs no SLA | | --- | --- | --- | --- | -| Excellent (~100%) | $84 compute + $0.20 SLA charge | — | −$0.20 | -| Good (~99%) | $84 + $0.20 | Small credit | Roughly −$0.17 | +| Excellent (~100%) | $84 compute + $0.20 SLA charge | — | −$0.20 (you paid the SLA charge) | +| Good (~99%) | $84 + $0.20 | Often none / small credit | Roughly −$0.20 to −$0.17 | | At target (~95%) | $84 + $0.20 | ~$42 credit | ~+$42 | | Severe outage (~90% or less) | $84 + $0.20 | ~$84 credit | ~+$84 | +Negative values in the last column mean you paid a small SLA charge on top of compute; positive values mean you received a settlement credit. Strong-uptime days often yield no credit in production settlement. + Production settlement uses the multi-window reliability blend described above, not a single raw daily percentage. Treat these rows as directional, not exact invoice amounts. @@ -143,11 +168,18 @@ Production settlement uses the multi-window reliability blend described above, n - Credits accumulate on your instance charges and transfer to your account balance. - When your contract ends, any remaining unsettled days are resolved at close. +## If your instance goes down + +1. Save work and check **Instances** for host/maintenance status. +2. Remember: compute and SLA charges continue until settlement; credits apply to the **previous UTC day**, not the current hour. +3. After settlement, check **Account → Billing** (Charges / billing history) for SLA line items. +4. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). + ## Viewing SLA on active instances On the [Instances](https://cloud.vast.ai/instances/) page, price details for SLA rentals include the SLA charge rate alongside GPU and storage costs. -The [show instances API](/api-reference/instances/show-instances) exposes SLA fields on each contract: +Show-instances output may include: | Field | Meaning | | --- | --- | @@ -156,10 +188,24 @@ The [show instances API](/api-reference/instances/show-instances) exposes SLA fi | `sla_sigma_x` | Host's confidence spread | | `search.slaPremiumPerHour` | Current SLA charge rate (API field name) | -Filter active instances with `has_sla=true` in the query. +To find SLA-covered instances, inspect returned objects for `target_reliability > 0` (or filter in your client). The show-instances API does **not** support a `has_sla` query parameter. + +
+API integrators — field aliases + +| Console / concept | API / raw field | +| --- | --- | +| Host SLA claim | `expected_reliability` on offers; `sla_r_claim` on contracts | +| Host confidence | `sla_sigma_x` | +| SLA charge rate | `search.slaPremiumPerHour` / `instance.slaPremiumPerHour` | +| Your target | `target_reliability` | + +These fields appear in CLI `--raw` output when SLA is active. Confirm against a live `--raw` response before building parsers. +
## When SLA is not available +- **Interruptible (bid) rentals** never include SLA, even on SLA-enabled machines. Use on-demand with a reliability target set. - **Prepaid / reserved-only flows** may reject SLA parameters. Use on-demand rentals for SLA coverage. - Offers without SLA (`expected_reliability = 0` / `has_sla=false`) are excluded when you filter with `has_sla=true` or set a positive `target_reliability`. - If SLA parameters on an offer are invalid for your target, search may flag an SLA pricing error instead of showing a charge. @@ -176,11 +222,11 @@ No. The target is fixed when the contract is created. End the instance and rent ### Does SLA replace verification? -No. Verification is a platform quality signal. SLA is a financial guarantee on a specific contract. A verified machine can still have SLA; an unverified machine may also offer SLA. +No. Verification is a platform quality signal (see [Machine Tiers](/guides/instances/choosing/find-and-rent#machine-tiers)). SLA is a financial guarantee on a specific contract. ### Where do I see historical SLA credits? -Check your billing history and instance charges. SLA line items appear alongside compute charges for each settled day. +Check **Account → Billing** and instance charges. SLA line items appear alongside compute charges for each settled day. ## Related documentation diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 9bd0029c..a79c1238 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -315,7 +315,9 @@ If the machine loses connection, or if a client instance fails to start, the mac ### How do I minimize my reliability dropping? -Do not take your machine offline. If you must take your machine offline, minimize the time you have it offline. Note: reliability takes into account the average earnings of the machine, and machines with less earnings get penalized less from offline time. +Do not take your machine offline. If you must take your machine offline, minimize the time you have it offline. + +This advice applies to your marketplace **reliability score**, not SLA settlement. The dashboard score reflects connection and start reliability over recent activity. SLA uses separate measurement and daily credits — see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability). ### If someone has already used an image on my machine does redownload happen or is the system smart? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index eb18540a..dd9554a9 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -27,11 +27,19 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative ## Before you enable SLA +**Pre-flight checklist (before tuning claim/confidence):** + +- Confirm SLA is enabled for your account (contact [Discord](https://discord.gg/hSuEbSQ4X8) / support if unsure). +- Ensure your host daemon is current per the [host setup guide](https://cloud.vast.ai/host/setup/). +- If listing fails with `sla_not_approved` or `sla_daemon_outdated`, resolve eligibility before changing SLA parameters. + Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machine appears on **Host → Machines** with no red error status. Before enabling SLA, finish normal listing setup: test your machine, set GPU price and offer end date, choose on-demand vs interruptible, and understand [Testing your own machine](/host/hosting-overview#testing-your-own-machine) and offer terms in [Hosting overview](/host/hosting-overview). -SLA listing may require host approval and a sufficiently recent daemon. If listing fails with `sla_not_approved` or `sla_daemon_outdated`, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or update the daemon from the host setup page. + +On outage days you may still bill clients for **intended** compute **and** owe SLA settlement credits. Tail-risk exposure can approach a full day’s compute per affected contract — not just the daily SLA charge shown in previews. Read [Billing vs settlement](#billing-vs-settlement-important) before enabling SLA. + **Rental types:** SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible instances on an SLA-enabled machine are not SLA-covered; on-demand contracts on the same machine are. If a client attempts to reserve or prepay an SLA-enabled offer, the request is rejected. @@ -89,7 +97,10 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | --- | --- | --- | --- | | Reliability claim | `sla_r_claim` | `r` (backtester sets claim = target = `r`) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | | Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the claim. Lower = more confident (lower SLA charges for clients at a given target). Defaults to `0.5` if omitted. | -| Max client β (optional) | `sla_max_beta` | — | Advanced term capping how path-dependent a client's timescale mix can be. Most hosts can omit this. Must be in `(0, 1)` and at least the default β derived at your claim. | + +### Advanced: `sla_max_beta` (optional) + +Omit unless Vast support directs you. Optional ask term `sla_max_beta` limits how path-dependent a client's timescale mix can be for long-running contracts. Must be in `(0, 1)` and at least the default β derived at your claim. Most hosts should leave it unset. **`sla_r_target` is not host-settable.** If you send `sla_r_target` or legacy `sla_reliability` on `create_asks/`, they are **ignored**. Clients supply their coverage target at search/rent time (`target_reliability`). Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x` — they use different scales. Use the mapping table on the [backtester page](/host/sla-backtester#confidence-values-p). @@ -108,7 +119,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / ### Machine reliability score vs SLA reliability -The **reliability score** on the Host Machines page reflects connection and instance-start behavior (and is earnings-weighted). **SLA settlement** measures whether covered instances met the client's published uptime target for billing purposes. +The **reliability score** on the Host Machines page reflects connection and instance-start behavior over recent activity. **SLA settlement** measures whether covered instances met the client's published uptime target for billing purposes. Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r_claim`: @@ -171,7 +182,9 @@ If the machine is already **listed**: 1. Open **Host → Machines → Set Pricing → SLA**, set Claim and Confidence, then click **Save**. 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. -3. Verify in search: `dph_total` includes the SLA charge at a client's `target_reliability`, and `expected_reliability` matches your claim (see [Search / client-visible fields](#search--client-visible-fields)). +3. Verify after listing: + - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. + - **Search:** `dph_total` includes the SLA charge at a client's `target_reliability`, and `expected_reliability` matches your claim (see [Search / client-visible fields](#search--client-visible-fields)). In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same as pressing **LIST** or running `vastai list machine`), not a save-only draft. @@ -413,6 +426,8 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi Maintenance windows scheduled through [`vastai schedule maint`](/host/cli/schedule-maint) may be credited back toward reliability, reducing SLA penalties for planned downtime. Unplanned outages count fully toward SLA settlement. +**Console-only hosts:** SLA credit for planned downtime requires scheduling maintenance at least 24 hours ahead. Today this is done via the CLI (`vastai schedule maint`). Install the CLI before enabling SLA if you rely on planned maintenance credits. + Planned maintenance credit is not guaranteed. The platform evaluates advance notice (generally at least 24 hours recommended) and maintenance duration when determining credit eligibility. **Treat any scheduled downtime as a potential SLA credit event when modeling risk.** Contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or email [contact@vast.ai](mailto:contact@vast.ai) before extended maintenance on an SLA-listed machine to confirm credit eligibility. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 07ea34e8..d935e4ad 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,9 +3,9 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA parameters (`--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). +SLA parameters (`--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation) and [List Machine](/api-reference/machines/list-machine). -For SLA listing via REST, see [SLA Offers — API (for automation)](/host/sla-offers#api-for-automation). Volume and duration options (`-v`, `-z`, `-l`) are available in the CLI today. REST callers should confirm supported `create_asks/` body fields in the [List Machine API reference](/api-reference/machines/list-machine) before sending them — some CLI-only fields may not yet appear in the published OpenAPI schema. +Volume and duration options (`-v`, `-z`, `-l`) are available in the CLI today. ## Usage From a747540806c4c2148191f1cda3fef1910d6bccac Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 13:53:32 -0700 Subject: [PATCH 018/250] docs(sla): address doc-review consensus (cycle 2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document search→rent SLA binding with REST examples, clarify console opt-in and maintenance CLI paths, and fix OpenAPI slaPremiumPerHour examples. Co-authored-by: Cursor --- api-reference/openapi.yaml | 51 ++++++++++---- api-reference/openapi/yaml/search_offers.yaml | 6 +- .../openapi/yaml/show_instances.yaml | 28 +++++--- cli/reference/search-offers.mdx | 3 +- guides/instances/choosing/find-and-rent.mdx | 7 +- guides/instances/choosing/sla-coverage.mdx | 67 ++++++++++++------- host/hosting-overview.mdx | 10 ++- host/sla-offers.mdx | 15 ++++- snippets/host/cli/schedule-maint.mdx | 4 +- 9 files changed, 130 insertions(+), 61 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 54e3bed5..eba64977 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6940,12 +6940,6 @@ paths: webpage: null vms_enabled: false expected_reliability: 0.99 - search: - gpuCostPerHour: 0.123456 - diskHour: 0.123456 - totalHour: 0.234567 - discountTotalHour: 0.01 - discountedTotalPerHour: 0.224567 is_vm_deverified: false resource_type: gpu cluster_id: null @@ -6961,9 +6955,17 @@ paths: discount_rate: 0.05 discounted_hourly: 0.01 discounted_dph_total: 0.224567 + search: + gpuCostPerHour: 0.123456 + diskHour: 0.123456 + slaPremiumPerHour: 0.008 + totalHour: 0.234567 + discountTotalHour: 0.01 + discountedTotalPerHour: 0.224567 instance: gpuCostPerHour: 0.01 diskHour: 0.02 + slaPremiumPerHour: 0.008 totalHour: 0.03 discountTotalHour: 0.001 discountedTotalPerHour: 0.029 @@ -8400,14 +8402,6 @@ paths: nullable: true description: Host confidence spread for this SLA contract. example: 0.5 - search: - type: object - example: - gpuCostPerHour: 0.8 - diskHour: 0.0021 - totalHour: 0.8021 - discountTotalHour: 0 - discountedTotalPerHour: 0.8013 dlperf: type: - number @@ -8459,11 +8453,40 @@ paths: - string - 'null' example: null + search: + type: object + description: Price breakdown for search-context costs (may + include slaPremiumPerHour). + additionalProperties: true + properties: + slaPremiumPerHour: + type: number + format: float + description: SLA charge rate in $/hour (API field name). + example: 0.008 + example: + gpuCostPerHour: 0.8 + diskHour: 0.0021 + slaPremiumPerHour: 0.008 + totalHour: 0.8021 + discountTotalHour: 0 + discountedTotalPerHour: 0.8013 instance: type: object + description: Price breakdown for instance-context costs + (may include slaPremiumPerHour while running). + additionalProperties: true + properties: + slaPremiumPerHour: + type: number + format: float + description: SLA charge rate in $/hour while the instance + is running (API field name). + example: 0.008 example: gpuCostPerHour: 0.8 diskHour: 0.0013 + slaPremiumPerHour: 0.008 totalHour: 0.8021 discountTotalHour: 0 discountedTotalPerHour: 0.5034 diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index 93a834dc..16ab5bbe 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -379,10 +379,6 @@ paths: webpage: null vms_enabled: false expected_reliability: 0.99 - search: - slaPremiumPerHour: 0.008 - gpuCostPerHour: 3.5 - totalHour: 3.508 is_vm_deverified: false resource_type: "gpu" cluster_id: null @@ -401,12 +397,14 @@ paths: search: gpuCostPerHour: 0.123456 diskHour: 0.123456 + slaPremiumPerHour: 0.008 totalHour: 0.234567 discountTotalHour: 0.01 discountedTotalPerHour: 0.224567 instance: gpuCostPerHour: 0.01 diskHour: 0.02 + slaPremiumPerHour: 0.008 totalHour: 0.03 discountTotalHour: 0.001 discountedTotalPerHour: 0.029 diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index d280c1d1..88f4bf83 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -354,16 +354,6 @@ paths: nullable: true description: Host confidence spread for this SLA contract. example: 0.5 - search: - type: object - description: Price breakdown for search-context costs (may include slaPremiumPerHour). - additionalProperties: true - properties: - slaPremiumPerHour: - type: number - format: float - description: SLA charge rate in $/hour (API field name). - example: 0.008 dlperf: type: number nullable: true @@ -412,17 +402,35 @@ paths: example: null search: type: object + description: Price breakdown for search-context costs (may include slaPremiumPerHour). + additionalProperties: true + properties: + slaPremiumPerHour: + type: number + format: float + description: SLA charge rate in $/hour (API field name). + example: 0.008 example: gpuCostPerHour: 0.8 diskHour: 0.0021 + slaPremiumPerHour: 0.008 totalHour: 0.8021 discountTotalHour: 0 discountedTotalPerHour: 0.8013 instance: type: object + description: Price breakdown for instance-context costs (may include slaPremiumPerHour while running). + additionalProperties: true + properties: + slaPremiumPerHour: + type: number + format: float + description: SLA charge rate in $/hour while the instance is running (API field name). + example: 0.008 example: gpuCostPerHour: 0.8 diskHour: 0.0013 + slaPremiumPerHour: 0.008 totalHour: 0.8021 discountTotalHour: 0 discountedTotalPerHour: 0.5034 diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index b31331b4..731e0a02 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -147,10 +147,11 @@ vastai search offers 'cpu_arch=arm64' | `num_gpus` | int | number of GPUs | | `pci_gen` | float | PCIE generation | | `pcie_bw` | float | PCIE bandwidth (CPU to GPU) | +| `dph_total` | float | total $/hr in search results (compute + storage + SLA charge when applicable) | | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability claim on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | -| `target_reliability` | float | your desired SLA coverage level; drives SLA charge in `dph_total` | +| `target_reliability` | float | your desired SLA coverage level; drives SLA charge in `dph_total` (see [SLA Coverage](/guides/instances/choosing/sla-coverage)) | | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 08c75f4e..b4b998d7 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -21,7 +21,7 @@ You will find various search options on the top and left control bars that allow The offer card shows the details of a machine available for rent, including specs, pricing, and the maximum rental duration. When you rent an instance, a rental contract is created between you and the host based on the offer's current terms. The offer remains available for other clients until it reaches its end date or is unlisted by the host. -Most of the items on the offer card can be filtered using the search filters. Some of the important parts are the price and the maximum rental duration. Hovering over the price details the different prices for GPU rental, storage and bandwidth. +Most of the items on the offer card can be filtered using the search filters. Some of the important parts are the price and the maximum rental duration. Hovering over the price shows the different prices for GPU rental, storage, and bandwidth. ### Machine Tiers @@ -46,7 +46,7 @@ All stats shown are the portion of the total machine rented. - Motherboard: The name of the motherboard manufacturer and type - Motherboard details: PCIE version and number of lanes along with maximum theoretical PCIE bandwidth in GB/s - CPU: The CPU type -- CPU Cores: the number of cores allocated for this offer divided total +- CPU Cores: the number of cores allocated for this offer divided by the total - System RAM: system RAM allocated for this offer divided by the total - Network Bandwidth: Given in Mbps for upload/download - Network Ports: number of potential ports available @@ -57,7 +57,8 @@ All stats shown are the portion of the total machine rented. - Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. On SLA listings, the breakdown also shows an **SLA charge** line — see [SLA Coverage](/guides/instances/choosing/sla-coverage). - Max Duration: The maximum length of a rental contract on this machine - Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host SLA claim. - Rental Option: RENT Button +- Rental Option: RENT button +- **SLA (optional):** Available on **on-demand** rentals only. Set a **reliability target** in Search before clicking **RENT** to opt in — see [SLA Coverage](/guides/instances/choosing/sla-coverage). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 0b01823b..0a4d0677 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -62,10 +62,10 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 ### In the web console -1. Open [Search](https://cloud.vast.ai/create/). -2. Set your **reliability target** in Search filters (and optionally filter to SLA-enabled offers). Exact control labels match the UI. -3. Confirm the price breakdown shows an **SLA charge** line and that **total $/hr** includes it before you rent. -4. The target you set here is what locks in at rent time. +1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). +2. In the search filters panel, set your **reliability target** (exact label matches the current UI—typically under advanced or SLA filters). +3. Review offers that show an **SLA charge** line in the price breakdown. If you do not see an SLA charge before clicking **RENT**, you do not have coverage. +4. Rent as usual. Your target is locked at rent time. CLI and API examples below use the same filters. @@ -116,11 +116,32 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Search ran ### API automation -1. **Search** with `target_reliability` set (and optionally `has_sla=true`, `expected_reliability>=…`) in the same request you use to pick an offer. -2. **Rent** the offer ID from that search response so pricing and contract terms match `dph_total`. -3. **Verify** on the new instance: `target_reliability` and related SLA fields in show-instances output. + +Searching without `target_reliability`, then calling create-instance on that offer ID, does **not** add SLA retroactively. SLA terms are locked only when `target_reliability` is set in the **same** search request used to select the offer. + -`target_reliability` is a **search-time** parameter; create-instance does not accept separate SLA fields — terms come from the search context used before rent. +**REST search example** (filter shape differs from CLI query strings — see [Search Offers](/api-reference/search/search-offers)): + +```bash +curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "limit": 20, + "type": "ondemand", + "target_reliability": {"eq": 0.95}, + "has_sla": {"eq": true}, + "expected_reliability": {"gte": 0.99} + }' +``` + +1. **Search** with your target as above (and optionally `has_sla` / `expected_reliability`). +2. **Rent** the chosen offer with `PUT /api/v0/asks/{id}/` ([Create Instance](/api-reference/instances/create-instance)) — no SLA fields on create-instance. +3. **Verify** via show-instances: confirm `target_reliability > 0` and note `search.slaPremiumPerHour`. + +If your automation splits search and rent across workers, pass the search parameters (or offer ID plus confirmed `dph_total` and `target_reliability`) explicitly between steps — do not assume account-wide defaults apply SLA. + +Hold `--storage` / allocated storage constant when comparing `dph_total` across runs. ## What happens after you rent @@ -149,14 +170,15 @@ Scheduled maintenance with adequate notice may be credited toward reliability. U Using the H100 example ($84/day compute, ~$0.20/day SLA charge, target 95%, host claim 99%): -| Day's measured reliability (simplified) | What you pay | What you receive | Extra cost vs no SLA | +| Scenario | Approx. SLA charge | Approx. settlement credit | Net vs no SLA (approx.) | | --- | --- | --- | --- | -| Excellent (~100%) | $84 compute + $0.20 SLA charge | — | −$0.20 (you paid the SLA charge) | -| Good (~99%) | $84 + $0.20 | Often none / small credit | Roughly −$0.20 to −$0.17 | -| At target (~95%) | $84 + $0.20 | ~$42 credit | ~+$42 | -| Severe outage (~90% or less) | $84 + $0.20 | ~$84 credit | ~+$84 | +| Above target (excellent / good day) | ~$0.20/day | $0 (often) | **−$0.20** (you paid the SLA charge) | +| Near / below target on blended measure (~95%) | ~$0.20/day | ~$42 | **+$41.80** (net credit after SLA charge) | +| Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | + +**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without SLA coverage. -Negative values in the last column mean you paid a small SLA charge on top of compute; positive values mean you received a settlement credit. Strong-uptime days often yield no credit in production settlement. +Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. Production settlement uses the multi-window reliability blend described above, not a single raw daily percentage. Treat these rows as directional, not exact invoice amounts. @@ -177,18 +199,17 @@ Production settlement uses the multi-window reliability blend described above, n ## Viewing SLA on active instances -On the [Instances](https://cloud.vast.ai/instances/) page, price details for SLA rentals include the SLA charge rate alongside GPU and storage costs. +### In the web console -Show-instances output may include: +1. Open **Instances** and select your running instance. +2. Open **price details** (or the instance billing panel) and confirm an **SLA charge** line is present. +3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. If you do not see a target or SLA charge, you likely rented without SLA coverage. -| Field | Meaning | -| --- | --- | -| `target_reliability` | Your coverage target | -| `sla_r_claim` | Host's claim | -| `sla_sigma_x` | Host's confidence spread | -| `search.slaPremiumPerHour` | Current SLA charge rate (API field name) | +### API / CLI + +Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). -To find SLA-covered instances, inspect returned objects for `target_reliability > 0` (or filter in your client). The show-instances API does **not** support a `has_sla` query parameter. +To find SLA-covered instances, inspect returned objects for `target_reliability > 0` (or filter in your client). The show-instances API does **not** support a `has_sla` query parameter. Where your API key supports it, you may also try `select_filters` on `sla_r_target` / `target_reliability` — see [Show Instances](/api-reference/instances/show-instances).
API integrators — field aliases diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index a79c1238..86268bae 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -235,7 +235,12 @@ The proper way to perform maintenance on your machine is to wait until all activ Unlisting the offer will prevent new rental contracts from being created, but does not affect existing ones. However if you have active rental contracts, you could set the offer end date to match the latest rental end date, allowing new clients to rent instances that end at the same date. Once the end date is reached, you can then unlist the machine and then perform maintenance. -Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. You cannot take the machine offline until every active rental contract has ended. +Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. + +You have two maintenance paths: + +1. **After contracts end:** Take the machine offline once every active rental contract has ended (default path). +2. **During active SLA contracts:** Use planned maintenance via [`vastai schedule maint`](/host/cli/schedule-maint) with at least 24 hours’ notice. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance) for credit rules. For unplanned or unscheduled maintenance, use the CLI and the [`vastai schedule maint`](/host/cli/schedule-maint) command. That will notify the client that you **have** to take the machine down and that they should save their work. You can specify a date and duration. @@ -267,8 +272,9 @@ You can create an invoice by going to the "Billing" page, and then click the box If your machine seems unlisted or missing from console search: +- Confirm **Listed** status on **Host → Machines**. - **CLI check:** `vastai search offers 'machine_id=MACHINE_ID verified=any'` — if this returns a result, your machine is listed. -- **Console search:** There are 10,000+ listings; search shows a small subset. You usually cannot find one specific machine through normal browsing — this is expected. +- Individual machines can be hard to find in broad console search; looking up by `machine_id` is the reliable check. - **Ranking check:** Use narrow filters to see similar machines, e.g. `vastai search offers 'gpu_name=RTX_4090 cpu_ram>257 cpu_ram<258'`. See also [Why is my machine not listed?](#why-is-my-machine-not-listed) below. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index dd9554a9..a2607f09 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -29,9 +29,10 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative **Pre-flight checklist (before tuning claim/confidence):** -- Confirm SLA is enabled for your account (contact [Discord](https://discord.gg/hSuEbSQ4X8) / support if unsure). +- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) before configuring a fleet. Test one machine before looping fleet scripts. - Ensure your host daemon is current per the [host setup guide](https://cloud.vast.ai/host/setup/). - If listing fails with `sla_not_approved` or `sla_daemon_outdated`, resolve eligibility before changing SLA parameters. +- **Planned maintenance:** SLA credit for scheduled downtime requires the [CLI](/cli/hello-world) (`vastai schedule maint`). If you rely on the web console only, install the CLI before enabling SLA, or accept that planned-maintenance credits may not be available until you do. Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machine appears on **Host → Machines** with no red error status. @@ -172,7 +173,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. -4. Set **Claim** and **Confidence** (spread). Example: claim **99%** with normal confidence. +4. Set **Claim** and **Confidence**. For your first listing, choose **Normal** (`sla_sigma_x ≈ 0.5`) unless your uptime history is volatile — see [Confidence values](#confidence-values) for risk tradeoffs. 5. Save and confirm the SLA charge preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. @@ -426,7 +427,15 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi Maintenance windows scheduled through [`vastai schedule maint`](/host/cli/schedule-maint) may be credited back toward reliability, reducing SLA penalties for planned downtime. Unplanned outages count fully toward SLA settlement. -**Console-only hosts:** SLA credit for planned downtime requires scheduling maintenance at least 24 hours ahead. Today this is done via the CLI (`vastai schedule maint`). Install the CLI before enabling SLA if you rely on planned maintenance credits. +Schedule at least 24 hours ahead when possible: + +```bash +vastai schedule maint MACHINE_ID --sdate "2026-08-01 02:00:00" --duration 2 +``` + +See [CLI install](/cli/hello-world) if you have not set up the CLI. Credits for planned maintenance are evaluated on a case-by-case basis and are not guaranteed. + +**Console-only hosts:** install the CLI before enabling SLA if you rely on planned maintenance credits. Planned maintenance credit is not guaranteed. The platform evaluates advance notice (generally at least 24 hours recommended) and maintenance duration when determining credit eligibility. **Treat any scheduled downtime as a potential SLA credit event when modeling risk.** Contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or email [contact@vast.ai](mailto:contact@vast.ai) before extended maintenance on an SLA-listed machine to confirm credit eligibility. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 196ca1ba..4c15dee8 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -5,9 +5,11 @@ Schedule upcoming maint window ## Usage ```bash -vastai schedule maintenance id [--sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY] +vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY] ``` +`schedule maintenance` is an alias for `schedule maint` if your CLI build supports both spellings. Prefer `maint`. + ## Arguments From e740d4c80beb0a3ab50df0afef64b31ae24396cb Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 13:59:30 -0700 Subject: [PATCH 019/250] docs(sla): address doc-review consensus (cycle 3) Document create-instance target_reliability binding, align schedule-maint sdate formats, and harden search/rent API examples. Co-authored-by: Cursor --- api-reference/openapi.yaml | 30 ++++++++++++-- .../openapi/yaml/create_instance.yaml | 11 ++++++ .../openapi/yaml/schedule_maint.yaml | 7 +++- api-reference/openapi/yaml/search_offers.yaml | 2 +- cli/reference/search-offers.mdx | 4 +- guides/instances/choosing/sla-coverage.mdx | 39 ++++++++++++------- host/sla-backtester.mdx | 4 +- host/sla-offers.mdx | 18 +++++---- snippets/host/cli/schedule-maint.mdx | 2 +- 9 files changed, 86 insertions(+), 31 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index eba64977..cc47388e 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1648,6 +1648,20 @@ paths: format: float description: 'Size of local disk partition (in GB) + ' + target_reliability: + type: number + format: float + minimum: 0 + exclusiveMaximum: true + description: 'Client SLA coverage target (greater than 0 and less + than 1). When set on an SLA-enabled offer + + (`sla_r_claim > 0`), locks SLA terms on the new contract. Omit + or set to 0 for a non-SLA rental. + + Use the same value you used in search when comparing `dph_total`. + ' runtype: type: string @@ -1774,6 +1788,8 @@ paths: (e.g., `/workspace`) example: image: vastai/base-image:@vastai-automatic-tag + disk: 50 + target_reliability: 0.95 responses: '200': description: Instance created successfully @@ -6367,8 +6383,16 @@ paths: sdate: type: string format: date-time - description: Start date and time of the maintenance window. - example: '2023-10-30T14:00:00Z' + description: 'Start date and time of the maintenance window as an + ISO 8601 UTC datetime + + (for example `2026-08-01T02:00:00Z`). The CLI `--sdate` flag accepts + Unix epoch seconds + + and converts them to this format before calling the API. + + ' + example: '2026-08-01T02:00:00Z' duration: type: integer description: Duration of the maintenance window in hours. @@ -6841,7 +6865,7 @@ paths: ' example: limit: 100 - type: on-demand + type: ondemand verified: eq: true rentable: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 9bfbbea2..1306ca66 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -63,6 +63,15 @@ paths: format: float description: | Size of local disk partition (in GB) + target_reliability: + type: number + format: float + minimum: 0 + exclusiveMaximum: true + description: | + Client SLA coverage target (greater than 0 and less than 1). When set on an SLA-enabled offer + (`sla_r_claim > 0`), locks SLA terms on the new contract. Omit or set to 0 for a non-SLA rental. + Use the same value you used in search when comparing `dph_total`. runtype: type: string description: | @@ -162,6 +171,8 @@ paths: description: Mount path for the volume inside the container (e.g., `/workspace`) example: image: vastai/base-image:@vastai-automatic-tag + disk: 50 + target_reliability: 0.95 responses: '200': description: Instance created successfully diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index d8deafed..18b3a1cc 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -37,8 +37,11 @@ paths: sdate: type: string format: date-time - description: Start date and time of the maintenance window. - example: '2023-10-30T14:00:00Z' + description: | + Start date and time of the maintenance window as an ISO 8601 UTC datetime + (for example `2026-08-01T02:00:00Z`). The CLI `--sdate` flag accepts Unix epoch seconds + and converts them to this format before calling the API. + example: '2026-08-01T02:00:00Z' duration: type: integer description: Duration of the maintenance window in hours. diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index 16ab5bbe..b93c497b 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -282,7 +282,7 @@ paths: Default is 8GB. example: limit: 100 - type: on-demand + type: ondemand verified: eq: true rentable: diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 731e0a02..b3ee1050 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -44,7 +44,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] - New search exp + Use the experimental search path (internal / unstable). Prefer the default search for production and SLA filtering. @@ -151,7 +151,7 @@ vastai search offers 'cpu_arch=arm64' | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability claim on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | -| `target_reliability` | float | your desired SLA coverage level; drives SLA charge in `dph_total` (see [SLA Coverage](/guides/instances/choosing/sla-coverage)) | +| `target_reliability` | float | your desired SLA coverage level (greater than 0 and less than 1); drives SLA charge in `dph_total` (see [SLA Coverage](/guides/instances/choosing/sla-coverage)) | | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 0a4d0677..c6ec7ef0 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -9,7 +9,7 @@ Some Vast.ai offers include a **Service Level Agreement (SLA)** — a reliabilit This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. -**SLA is opt-in.** Coverage applies only when you set a reliability target in Search before you rent (console or `target_reliability` in API/CLI). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. +**SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via API/CLI, pass `target_reliability` on **create-instance** (and in search when pricing). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. @@ -44,7 +44,7 @@ total ≈ GPU + storage + bandwidth + SLA charge | --- | --- | | Your reliability target | Higher target → higher SLA charge | | Host SLA claim | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher claim → lower SLA charge at a given target | -| Host confidence | Host pricing setting that affects SLA charge size (tighter = lower charge at a given target) | +| Host confidence | Host-side pricing setting that affects SLA charge size. **Not shown on offer cards** — compare offers using `dph_total` or the SLA charge line in the price breakdown | **Rule of thumb:** pick a target **at or below** the host's claim for the best value. Asking for 99% coverage on a host who only claims 95% costs much more than asking for 95% on a host who claims 99%. @@ -63,9 +63,10 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 ### In the web console 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). -2. In the search filters panel, set your **reliability target** (exact label matches the current UI—typically under advanced or SLA filters). -3. Review offers that show an **SLA charge** line in the price breakdown. If you do not see an SLA charge before clicking **RENT**, you do not have coverage. -4. Rent as usual. Your target is locked at rent time. +2. In the left/top **search filters** panel, find the **reliability target** / SLA filter control (label matches the current UI). Set your target (for example 95%). +3. Optionally filter to SLA-enabled offers if that control is available. +4. Review offers that show an **SLA charge** line in the price breakdown. If you do not see an SLA charge before clicking **RENT**, you do not have coverage. +5. Rent as usual. Your target is locked at rent time. CLI and API examples below use the same filters. @@ -117,10 +118,10 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Search ran ### API automation -Searching without `target_reliability`, then calling create-instance on that offer ID, does **not** add SLA retroactively. SLA terms are locked only when `target_reliability` is set in the **same** search request used to select the offer. +SLA coverage is locked at **create-instance** time via `target_reliability` on `PUT /api/v0/asks/{id}/`. Searching with a target only prices offers; renting without passing `target_reliability` on create-instance produces a **non-SLA** contract. -**REST search example** (filter shape differs from CLI query strings — see [Search Offers](/api-reference/search/search-offers)): +**1. Search** (prices `dph_total` at your target — include storage explicitly; REST defaults to 8 GB, CLI `--storage` defaults to 5 GiB): ```bash curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ @@ -129,19 +130,31 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ -d '{ "limit": 20, "type": "ondemand", + "allocated_storage": 50, "target_reliability": {"eq": 0.95}, "has_sla": {"eq": true}, "expected_reliability": {"gte": 0.99} }' ``` -1. **Search** with your target as above (and optionally `has_sla` / `expected_reliability`). -2. **Rent** the chosen offer with `PUT /api/v0/asks/{id}/` ([Create Instance](/api-reference/instances/create-instance)) — no SLA fields on create-instance. -3. **Verify** via show-instances: confirm `target_reliability > 0` and note `search.slaPremiumPerHour`. +**2. Rent** the chosen offer ID and pass the **same** target: -If your automation splits search and rent across workers, pass the search parameters (or offer ID plus confirmed `dph_total` and `target_reliability`) explicitly between steps — do not assume account-wide defaults apply SLA. +```bash +curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "image": "pytorch/pytorch:latest", + "disk": 50, + "target_reliability": 0.95 + }' +``` + +See [Create Instance](/api-reference/instances/create-instance) and [Search Offers](/api-reference/search/search-offers). + +**3. Verify** via show-instances: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. -Hold `--storage` / allocated storage constant when comparing `dph_total` across runs. +Hold `allocated_storage` / `--storage` constant when comparing `dph_total` across runs or between CLI and REST. ## What happens after you rent @@ -209,7 +222,7 @@ Production settlement uses the multi-window reliability blend described above, n Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). -To find SLA-covered instances, inspect returned objects for `target_reliability > 0` (or filter in your client). The show-instances API does **not** support a `has_sla` query parameter. Where your API key supports it, you may also try `select_filters` on `sla_r_target` / `target_reliability` — see [Show Instances](/api-reference/instances/show-instances). +To find SLA-covered instances, filter client-side from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Server-side `select_filters` on SLA fields is not guaranteed for all API keys — do not depend on it in production automation.
API integrators — field aliases diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 6bac61be..d32c6872 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -57,7 +57,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). - The backtester sets claim equal to target and may show higher SLA charges than live listing when clients choose targets below your claim. - For client-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or search with a realistic `target_reliability`. - For tail risk, trust `worst_day_loss`, not headline `total_sla`. -- Timescale mix (`β`) is derived from `r` for non-admin callers (same default a client targeting `r` would get). Admin overrides of `beta` are ignored for non-admins. +- Timescale mix (`β`) is derived from `r` for non-admin callers (same default a client targeting `r` would get). Hosts cannot set β via the listing API. ## Before you start @@ -91,7 +91,7 @@ Requires Bearer authentication. This endpoint is rate-limited like other host AP | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | | `reliability` | No | Optional flat uptime override (greater than 0 and at most 1). Ignores historical uptime — useful for what-if analysis. Use `0.01` to approximate near-total downtime; `0` is rejected with `400 bad_request`. | -| `beta` | No | Timescale mix override. For non-admins this is **ignored** — the API derives β from `r` (same default a client targeting `r` would get). Admins may override for analysis. | +| `beta` | No | Ignored for standard API keys — the API derives timescale weighting from `r`. | ### Limits diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a2607f09..a121461a 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -32,7 +32,7 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative - Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) before configuring a fleet. Test one machine before looping fleet scripts. - Ensure your host daemon is current per the [host setup guide](https://cloud.vast.ai/host/setup/). - If listing fails with `sla_not_approved` or `sla_daemon_outdated`, resolve eligibility before changing SLA parameters. -- **Planned maintenance:** SLA credit for scheduled downtime requires the [CLI](/cli/hello-world) (`vastai schedule maint`). If you rely on the web console only, install the CLI before enabling SLA, or accept that planned-maintenance credits may not be available until you do. +- **Planned maintenance:** SLA credit for scheduled downtime requires the [CLI](/cli/hello-world) or [REST schedule-maintenance API](/api-reference/machines/schedule-maint) (`vastai schedule maint`). The web console can configure SLA pricing, but **scheduling maintenance requires CLI or REST**. Install the CLI before enabling SLA if you plan maintenance windows. Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machine appears on **Host → Machines** with no red error status. @@ -425,17 +425,21 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi ### Scheduled maintenance -Maintenance windows scheduled through [`vastai schedule maint`](/host/cli/schedule-maint) may be credited back toward reliability, reducing SLA penalties for planned downtime. Unplanned outages count fully toward SLA settlement. +**Planned SLA maintenance (may earn credit):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate`, `--duration`, and `--maintenance_category planned`. Credit eligibility is evaluated on a case-by-case basis. -Schedule at least 24 hours ahead when possible: +**CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC: ```bash -vastai schedule maint MACHINE_ID --sdate "2026-08-01 02:00:00" --duration 2 +# Example: 2026-08-01 02:00:00 UTC → epoch seconds +# Linux: date -u -d '2026-08-01 02:00:00' +%s +vastai schedule maint MACHINE_ID --sdate 1785549600 --duration 2 --maintenance_category planned ``` -See [CLI install](/cli/hello-world) if you have not set up the CLI. Credits for planned maintenance are evaluated on a case-by-case basis and are not guaranteed. +REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate": "2026-08-01T02:00:00Z"` — see [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Console-only hosts:** install the CLI before enabling SLA if you rely on planned maintenance credits. +**Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice credits do not apply to unplanned outages. + +See [CLI install](/cli/hello-world) if you have not set up the CLI. Planned maintenance credit is not guaranteed. The platform evaluates advance notice (generally at least 24 hours recommended) and maintenance duration when determining credit eligibility. **Treat any scheduled downtime as a potential SLA credit event when modeling risk.** Contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or email [contact@vast.ai](mailto:contact@vast.ai) before extended maintenance on an SLA-listed machine to confirm credit eligibility. @@ -511,7 +515,7 @@ Positive `sla_earn` = net SLA charge you kept that period; negative = net credit `GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key. See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll no faster than about one request every two seconds per IP (`threshold=2.0`); back off on HTTP 429. +This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll at most about once every two seconds per IP; back off on HTTP 429. When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 4c15dee8..8eb31ae9 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -19,7 +19,7 @@ vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_c ## Options - maintenance start date in unix epoch time (UTC seconds) + Maintenance start time as Unix epoch seconds (UTC). Example: `1677562671`. The API receives an ISO 8601 UTC datetime after conversion. From f2ec2ff67d863d42d8717bba89dff5be4ef18c31 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 14:04:34 -0700 Subject: [PATCH 020/250] docs(sla): address doc-review consensus (cycle 4) Align schedule-maint category and framing with the API enum; clarify console SLA filter and outage billing. Co-authored-by: Cursor --- api-reference/openapi.yaml | 5 +-- .../openapi/yaml/schedule_maint.yaml | 4 +-- .../openapi/yaml/show_instances.yaml | 2 +- guides/instances/choosing/sla-coverage.mdx | 25 +++++++------ host/hosting-overview.mdx | 35 +++++-------------- host/sla-offers.mdx | 7 ++-- snippets/host/cli/schedule-maint.mdx | 25 ++++++++++--- 7 files changed, 53 insertions(+), 50 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index cc47388e..3c7d12d7 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8095,8 +8095,9 @@ paths: present). Computed fields (e.g. `dph_total`, `num_gpus`, `has_sla`) are not filterable and return 400. - To find SLA-covered instances, filter client-side on `target_reliability - > 0` or use `select_filters` on `sla_r_target` if supported for your key. + Prefer client-side filtering on `target_reliability > 0` for SLA-covered + instances. Optional `select_filters` on stored SLA fields may work for some + keys; do not rely on it as the only detection path. ' schema: diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index 18b3a1cc..447ab2c6 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -131,5 +131,5 @@ x-cli-commands: description: Schedule maintenance for a machine. endpoint: /api/v0/machines/{machine_id}/dnotify method: PUT - example: vast-ai schedule maint 12345 --sdate "2023-10-30T14:00:00Z" --duration - 2 + example: vastai schedule maint 12345 --sdate 1698674400 --duration 2 + --maintenance_category software diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index 88f4bf83..08f768fc 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -56,7 +56,7 @@ paths: JSON object of column filters. Supported operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `notin`. Filterable columns: `actual_status`, `gpu_name`, `verification`, `id`, `label`, and other columns stored directly on the contract record (including `sla_r_claim` and `sla_r_target` / `target_reliability` when present). Computed fields (e.g. `dph_total`, `num_gpus`, `has_sla`) are not filterable and return 400. - To find SLA-covered instances, filter client-side on `target_reliability > 0` or use `select_filters` on `sla_r_target` if supported for your key. + Prefer client-side filtering on `target_reliability > 0` for SLA-covered instances. Optional `select_filters` on stored SLA fields may work for some keys; do not rely on it as the only detection path. schema: type: string default: '{}' diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c6ec7ef0..8a45fce6 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -63,9 +63,9 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 ### In the web console 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). -2. In the left/top **search filters** panel, find the **reliability target** / SLA filter control (label matches the current UI). Set your target (for example 95%). +2. In the **search filters** panel, set **Reliability target** (or the current SLA / reliability filter control) to your desired level — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. 3. Optionally filter to SLA-enabled offers if that control is available. -4. Review offers that show an **SLA charge** line in the price breakdown. If you do not see an SLA charge before clicking **RENT**, you do not have coverage. +4. Before you click **RENT**, confirm the price breakdown shows an **SLA charge** line. No SLA charge means no SLA coverage for that rental. 5. Rent as usual. Your target is locked at rent time. CLI and API examples below use the same filters. @@ -167,7 +167,11 @@ When you rent an SLA-backed offer **with a target set**: ### What you pay during an outage -You are still charged for **compute and the SLA charge** for the rental day while the instance is unavailable. If you qualify for compensation, a **settlement credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. + +Billing continues during downtime. You are still charged for **compute, storage, and the SLA charge** while the contract exists and the instance is unavailable. Leaving a broken instance running continues those charges until you destroy it. + + +If you qualify for compensation, a **settlement credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. Destroying ends future daily charges; final SLA settlement still posts when the contract closes. ### How reliability is measured @@ -177,7 +181,7 @@ Each day, the platform tracks how long your instance was online. Settlement cons - A pattern of unreliable uptime produces larger credits over time. - One strong day after a weak week does not instantly reset everything. -Scheduled maintenance with adequate notice may be credited toward reliability. Unplanned outages count fully. +Scheduled maintenance with adequate advance notice (typically 24+ hours) may be credited toward reliability on a case-by-case basis. Check **Instances** status and any client notifications during downtime to distinguish planned maintenance from an unexpected outage. Unplanned outages count fully. ### Credit scenarios (simplified) @@ -222,19 +226,18 @@ Production settlement uses the multi-window reliability blend described above, n Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). -To find SLA-covered instances, filter client-side from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Server-side `select_filters` on SLA fields is not guaranteed for all API keys — do not depend on it in production automation. +To find SLA-covered instances, filter **client-side** from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Prefer client-side filtering in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone for SLA detection.
-API integrators — field aliases +API integrators — response field names (parsers only; console users can skip) -| Console / concept | API / raw field | +| Client-visible concept | API / raw field | | --- | --- | -| Host SLA claim | `expected_reliability` on offers; `sla_r_claim` on contracts | -| Host confidence | `sla_sigma_x` | +| Your reliability target | `target_reliability` | | SLA charge rate | `search.slaPremiumPerHour` / `instance.slaPremiumPerHour` | -| Your target | `target_reliability` | +| Host SLA claim (offers / contracts) | `expected_reliability` / `sla_r_claim` | -These fields appear in CLI `--raw` output when SLA is active. Confirm against a live `--raw` response before building parsers. +Host confidence is a host-side pricing setting and is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers.
## When SLA is not available diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 86268bae..92002c1f 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -231,28 +231,17 @@ You can then look at your [instance tab](https://cloud.vast.ai/instances/) to ma ## Maintenance -The proper way to perform maintenance on your machine is to wait until all active rental contracts have ended or the machine has no running instances. - -Unlisting the offer will prevent new rental contracts from being created, but does not affect existing ones. However if you have active rental contracts, you could set the offer end date to match the latest rental end date, allowing new clients to rent instances that end at the same date. Once the end date is reached, you can then unlist the machine and then perform maintenance. - Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. -You have two maintenance paths: - -1. **After contracts end:** Take the machine offline once every active rental contract has ended (default path). -2. **During active SLA contracts:** Use planned maintenance via [`vastai schedule maint`](/host/cli/schedule-maint) with at least 24 hours’ notice. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance) for credit rules. - -For unplanned or unscheduled maintenance, use the CLI and the [`vastai schedule maint`](/host/cli/schedule-maint) command. That will notify the client that you **have** to take the machine down and that they should save their work. You can specify a date and duration. +Unlisting the offer prevents new rentals but does not end existing ones. If you have active contracts, you can set the offer end date to match the latest rental end date so new clients rent instances that end together. Once that date is reached, unlist and perform maintenance. -### If you have SLA enabled on this machine +Use these paths in order: -SLA-listed machines have additional maintenance obligations: +1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. +2. **Planned SLA maintenance (active renters):** If SLA is enabled, use [`vastai schedule maint`](/host/cli/schedule-maint) with a start time at least 24 hours in the future. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance) for credit eligibility. +3. **Emergency or unplanned downtime:** Use [`vastai schedule maint`](/host/cli/schedule-maint) immediately to notify renters. Full SLA settlement exposure may apply. -- Give at least **24 hours' notice** before planned downtime when possible. -- Use [`vastai schedule maint`](/host/cli/schedule-maint) and configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled` if you want your own alerts. -- Uptime credits during maintenance are evaluated case by case — see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). - -General maintenance guidance above applies to all hosts regardless of SLA. +The same `schedule maint` command supports planned and emergency notifications; advance notice and duration determine SLA credit eligibility. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. ## Uninstalling @@ -268,17 +257,15 @@ Hosting on Vast will require some Linux knowledge, as you will be maintaining a You can create an invoice by going to the "Billing" page, and then click the box for "Include Charges" under "Generate Billing History". -### Why can't I find my machine in search? +### Why can't I find my machine in search? / Why is my machine not listed? If your machine seems unlisted or missing from console search: -- Confirm **Listed** status on **Host → Machines**. -- **CLI check:** `vastai search offers 'machine_id=MACHINE_ID verified=any'` — if this returns a result, your machine is listed. +- Confirm **Listed** status on **Host → Machines** (console). +- **CLI check:** `vastai search offers 'machine_id=MACHINE_ID verified=any'` — if this returns a result, your machine is listed. The GUI may lag behind CLI visibility. - Individual machines can be hard to find in broad console search; looking up by `machine_id` is the reliable check. - **Ranking check:** Use narrow filters to see similar machines, e.g. `vastai search offers 'gpu_name=RTX_4090 cpu_ram>257 cpu_ram<258'`. -See also [Why is my machine not listed?](#why-is-my-machine-not-listed) below. - ### How does verification work? Verification is fully automated with no manual intervention. It depends on your machine's reliability, infrastructure, DLPerf score, and current supply and demand. See [Understanding Verification](/host/understanding-verification). @@ -295,10 +282,6 @@ You can use the [uninstall script](https://s3.amazonaws.com/vast.ai/uninstall) If the hosting software detects an error, that error message will be listed on your machine in the machines page. Once the cause of the error has been resolved, most error messages will be automatically cleared after 1-2 hours. The quickest way to learn more about resolving specific error messages is to check out the hosting channels in [our discord](https://discord.gg/hSuEbSQ4X8). -### Why is my machine not listed? - -You won't be able to see it on the GUI right away, but you can search using the [CLI](/guides/instances/managing-instances). See [Why can't I find my machine in search?](#why-cant-i-find-my-machine-in-search) above for the full checklist. - ### Can I send a message to a client using my machine letting them know that I fixed an issue that they were having? No, there is not an established process for hosts to message clients on Vast. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a121461a..5fea42bc 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -425,14 +425,15 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi ### Scheduled maintenance -**Planned SLA maintenance (may earn credit):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate`, `--duration`, and `--maintenance_category planned`. Credit eligibility is evaluated on a case-by-case basis. +**Planned SLA maintenance (may earn credit):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for SLA credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. Credit eligibility is evaluated on a case-by-case basis. -**CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC: +**CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** ```bash # Example: 2026-08-01 02:00:00 UTC → epoch seconds # Linux: date -u -d '2026-08-01 02:00:00' +%s -vastai schedule maint MACHINE_ID --sdate 1785549600 --duration 2 --maintenance_category planned +vastai schedule maint MACHINE_ID --sdate 1785549600 --duration 2 \ + --maintenance_category software --maintenance_reason "OS kernel upgrade" ``` REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate": "2026-08-01T02:00:00Z"` — see [Schedule Maintenance](/api-reference/machines/schedule-maint). diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 8eb31ae9..2c44b664 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -32,16 +32,31 @@ vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_c ## Description -The proper way to perform maintenance on your machine is to wait until all active contracts have expired or the machine is vacant. -For unplanned or unscheduled maintenance, use this schedule maint command. That will notify the client that you have to take the machine down and that they should save their work. -You can specify a date, duration, reason and category for the maintenance. +The lowest-risk path is to wait until all active contracts have expired or the machine is vacant, then take the machine offline. -Example: vastai schedule maint 8207 `--sdate` 1677562671 `--duration` 0.5 `--maintenance_category` "power" +The same `schedule maint` command is used for both **planned** and **emergency** downtime — advance notice and duration determine SLA credit eligibility, not the category value. + +### Planned SLA maintenance + +If SLA is enabled and you need planned downtime during an active rental, schedule at least 24 hours in advance. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). + +```bash +vastai schedule maint 8207 --sdate 1785549600 --duration 2 \ + --maintenance_category software --maintenance_reason "OS kernel upgrade" +``` + +### Emergency or unplanned maintenance + +If the machine must go offline without adequate notice, still run `schedule maint` to notify renters — but expect full SLA settlement exposure when SLA is enabled. + +```bash +vastai schedule maint 8207 --sdate 1677562671 --duration 0.5 --maintenance_category power +``` ## Examples ```bash -vastai schedule maint +vastai schedule maint --sdate --duration --maintenance_category software ``` ## Global Options From c9e38da468740520d8fb3df9b9b38779b886dada Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 14:08:56 -0700 Subject: [PATCH 021/250] docs(sla): address doc-review consensus (cycle 5) Clarify CLI create-instance lacks target_reliability; document REST-only maintenance_reason and raise maintenance tooling prerequisite. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 22 +++++++++++++++------- host/sla-offers.mdx | 14 +++++++++----- snippets/host/cli/schedule-maint.mdx | 7 +++++-- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 8a45fce6..078f5a15 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -9,7 +9,11 @@ Some Vast.ai offers include a **Service Level Agreement (SLA)** — a reliabilit This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. -**SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via API/CLI, pass `target_reliability` on **create-instance** (and in search when pricing). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. +**SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via the **REST API**, pass `target_reliability` on **create-instance** (`PUT /api/v0/asks/{id}/`). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. + + +`target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Searching with `target_reliability` only affects quoted pricing — it does **not** enable SLA on the contract unless you pass the same value at create-instance via **REST** or the **web console**. + @@ -63,7 +67,7 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 ### In the web console 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). -2. In the **search filters** panel, set **Reliability target** (or the current SLA / reliability filter control) to your desired level — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. +2. In Search filters (left filter bar), set **Reliability target** to your desired coverage level — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. 3. Optionally filter to SLA-enabled offers if that control is available. 4. Before you click **RENT**, confirm the price breakdown shows an **SLA charge** line. No SLA charge means no SLA coverage for that rental. 5. Rent as usual. Your target is locked at rent time. @@ -118,7 +122,7 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Search ran ### API automation -SLA coverage is locked at **create-instance** time via `target_reliability` on `PUT /api/v0/asks/{id}/`. Searching with a target only prices offers; renting without passing `target_reliability` on create-instance produces a **non-SLA** contract. +SLA coverage is locked at **create-instance** time via `target_reliability` on `PUT /api/v0/asks/{id}/` (REST). Searching with a target only prices offers. The published CLI/SDK create-instance path does **not** accept `target_reliability` yet — use REST or the console to rent with SLA. **1. Search** (prices `dph_total` at your target — include storage explicitly; REST defaults to 8 GB, CLI `--storage` defaults to 5 GiB): @@ -171,7 +175,9 @@ When you rent an SLA-backed offer **with a target set**: Billing continues during downtime. You are still charged for **compute, storage, and the SLA charge** while the contract exists and the instance is unavailable. Leaving a broken instance running continues those charges until you destroy it.
-If you qualify for compensation, a **settlement credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. Destroying ends future daily charges; final SLA settlement still posts when the contract closes. +**Stop vs destroy:** Stopping pauses compute but storage and contract charges can continue. **Destroying the instance** ends future daily charges; final SLA settlement still posts when the contract closes. If you abandon a failed host, destroy only after saving any data you need. + +If you qualify for compensation, a **settlement credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. ### How reliability is measured @@ -224,13 +230,15 @@ Production settlement uses the multi-window reliability blend described above, n ### API / CLI +Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. + +
+API integrators: field names and filters + Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). To find SLA-covered instances, filter **client-side** from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Prefer client-side filtering in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone for SLA detection. -
-API integrators — response field names (parsers only; console users can skip) - | Client-visible concept | API / raw field | | --- | --- | | Your reliability target | `target_reliability` | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 5fea42bc..0438df8f 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -27,12 +27,17 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative ## Before you enable SLA + +If you expect downtime during active rentals, install the [Vast CLI](/cli/hello-world) (or plan to use the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)) **before** enabling SLA. Planned SLA maintenance must be scheduled at least 24 hours ahead via CLI or REST — there is no in-console maintenance scheduler today. + + **Pre-flight checklist (before tuning claim/confidence):** -- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) before configuring a fleet. Test one machine before looping fleet scripts. +- Hosting requires a separate host account and hosting agreement — see [Account setup](/host/hosting-overview#account-setup-and-hosting-agreement) if you have not completed host onboarding. +- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai) to request access before configuring a fleet. Approval timing varies; complete host setup and a base listing first. - Ensure your host daemon is current per the [host setup guide](https://cloud.vast.ai/host/setup/). - If listing fails with `sla_not_approved` or `sla_daemon_outdated`, resolve eligibility before changing SLA parameters. -- **Planned maintenance:** SLA credit for scheduled downtime requires the [CLI](/cli/hello-world) or [REST schedule-maintenance API](/api-reference/machines/schedule-maint) (`vastai schedule maint`). The web console can configure SLA pricing, but **scheduling maintenance requires CLI or REST**. Install the CLI before enabling SLA if you plan maintenance windows. +- **Planned maintenance tooling:** Use [`vastai schedule maint`](/host/cli/schedule-maint) or REST — see [Scheduled maintenance](#scheduled-maintenance). Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machine appears on **Host → Machines** with no red error status. @@ -432,11 +437,10 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi ```bash # Example: 2026-08-01 02:00:00 UTC → epoch seconds # Linux: date -u -d '2026-08-01 02:00:00' +%s -vastai schedule maint MACHINE_ID --sdate 1785549600 --duration 2 \ - --maintenance_category software --maintenance_reason "OS kernel upgrade" +vastai schedule maint MACHINE_ID --sdate 1785549600 --duration 2 --maintenance_category software ``` -REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate": "2026-08-01T02:00:00Z"` — see [Schedule Maintenance](/api-reference/machines/schedule-maint). +REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate": "2026-08-01T02:00:00Z"` (optional `"maintenance_reason": "OS kernel upgrade"`) — see [Schedule Maintenance](/api-reference/machines/schedule-maint). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice credits do not apply to unplanned outages. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 2c44b664..3c27f94f 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -30,6 +30,10 @@ vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_c (optional) can be one of [power, internet, disk, gpu, software, other] + +Optional REST body field `maintenance_reason` (short description for notifications) is available on [Schedule Maintenance](/api-reference/machines/schedule-maint). The published CLI does not yet expose a `--maintenance_reason` flag. + + ## Description The lowest-risk path is to wait until all active contracts have expired or the machine is vacant, then take the machine offline. @@ -41,8 +45,7 @@ The same `schedule maint` command is used for both **planned** and **emergency** If SLA is enabled and you need planned downtime during an active rental, schedule at least 24 hours in advance. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ```bash -vastai schedule maint 8207 --sdate 1785549600 --duration 2 \ - --maintenance_category software --maintenance_reason "OS kernel upgrade" +vastai schedule maint 8207 --sdate 1785549600 --duration 2 --maintenance_category software ``` ### Emergency or unplanned maintenance From e8bbe37b4ff91fadc4568b2dc4780b05203ab033 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 14:14:00 -0700 Subject: [PATCH 022/250] docs(sla): address doc-review consensus (cycle 6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Harden search→rent SLA handoff, schedule-maint examples, earnings day indices, and create-instance error guidance. Co-authored-by: Cursor --- api-reference/openapi.yaml | 14 ++++++++++++-- api-reference/openapi/yaml/show_earnings.yaml | 8 ++++++-- cli/reference/search-offers.mdx | 7 +++++-- guides/instances/choosing/sla-coverage.mdx | 11 ++++++++++- host/sla-backtester.mdx | 4 ++-- host/sla-offers.mdx | 4 ++-- snippets/host/cli/schedule-maint.mdx | 14 ++++++++------ 7 files changed, 45 insertions(+), 17 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 3c7d12d7..795d97a0 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -7907,12 +7907,22 @@ paths: in: query schema: type: integer - description: Start day for the earnings report. + description: 'Start day for the earnings report as a UTC day index: + + `floor(unix_epoch_seconds / 86400)`. Prefer `last_days` when you do not + need an absolute window. + + ' - name: eday in: query schema: type: integer - description: End day for the earnings report. + description: 'End day for the earnings report as a UTC day index: + + `floor(unix_epoch_seconds / 86400)` (inclusive end of the window when used + with `sday`). + + ' - name: machid in: query schema: diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 5fe90ee1..2bee32a4 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -30,12 +30,16 @@ paths: in: query schema: type: integer - description: Start day for the earnings report. + description: | + Start day for the earnings report as a UTC day index: + `floor(unix_epoch_seconds / 86400)`. Prefer `last_days` when you do not need an absolute window. - name: eday in: query schema: type: integer - description: End day for the earnings report. + description: | + End day for the earnings report as a UTC day index: + `floor(unix_epoch_seconds / 86400)` (inclusive end of the window when used with `sday`). - name: machid in: query schema: diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index b3ee1050..16f47c49 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -44,7 +44,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] - Use the experimental search path (internal / unstable). Prefer the default search for production and SLA filtering. + Experimental search path — not recommended for production use. Prefer the default search for SLA filtering. @@ -82,6 +82,9 @@ bool = True | False vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=False' # SLA offers: host claim ≥ 99%, your coverage target 95% (see SLA Coverage) +# Search pricing only — target_reliability here quotes dph_total; it does not enable SLA on rent. +# To cover a rental: console Search target, or REST create-instance with target_reliability. +# vastai create instance does not support SLA yet. vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --order dph_total # datacenter GPUs with minimum compute capability and TFLOPs @@ -151,7 +154,7 @@ vastai search offers 'cpu_arch=arm64' | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability claim on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | -| `target_reliability` | float | your desired SLA coverage level (greater than 0 and less than 1); drives SLA charge in `dph_total` (see [SLA Coverage](/guides/instances/choosing/sla-coverage)) | +| `target_reliability` | float | your desired SLA coverage level (greater than 0 and less than 1); drives SLA charge in `dph_total` for **search quotes only**. Pass the same value at create-instance via console or REST to enable coverage — `vastai create instance` does not support SLA yet (see [SLA Coverage](/guides/instances/choosing/sla-coverage)) | | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 078f5a15..a07c4475 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -68,7 +68,7 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). 2. In Search filters (left filter bar), set **Reliability target** to your desired coverage level — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. -3. Optionally filter to SLA-enabled offers if that control is available. +3. Optionally filter to SLA-enabled offers (`has_sla` / SLA-enabled control) if available — separate from **Reliability target**. 4. Before you click **RENT**, confirm the price breakdown shows an **SLA charge** line. No SLA charge means no SLA coverage for that rental. 5. Rent as usual. Your target is locked at rent time. @@ -156,8 +156,17 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ See [Create Instance](/api-reference/instances/create-instance) and [Search Offers](/api-reference/search/search-offers). +**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and preferably `instance_read` (verify show-instances). See [Authentication](/api-reference/authentication) and [Permissions](/api-reference/permissions). + **3. Verify** via show-instances: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. +| Symptom | Typical response | What to do | +| --- | --- | --- | +| Target on a non-SLA offer | HTTP 400 `invalid_args` | Search with `has_sla=true`; confirm `expected_reliability` | +| Target out of range / invalid | HTTP 400 `invalid_args` | Use `0 < target_reliability < 1`; stay at or below a realistic host claim | +| Offer gone / not rentable | HTTP 404/410 `no_such_ask` | Re-search and rent a current offer ID | +| Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage, then rent again | + Hold `allocated_storage` / `--storage` constant when comparing `dph_total` across runs or between CLI and REST. ## What happens after you rent diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index d32c6872..6ddcc8c1 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -57,7 +57,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). - The backtester sets claim equal to target and may show higher SLA charges than live listing when clients choose targets below your claim. - For client-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or search with a realistic `target_reliability`. - For tail risk, trust `worst_day_loss`, not headline `total_sla`. -- Timescale mix (`β`) is derived from `r` for non-admin callers (same default a client targeting `r` would get). Hosts cannot set β via the listing API. +- Timescale mix (`β`) is derived from `r` (weights recent vs longer-term uptime in settlement). Hosts cannot set β via the listing API. ## Before you start @@ -91,7 +91,7 @@ Requires Bearer authentication. This endpoint is rate-limited like other host AP | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | | `reliability` | No | Optional flat uptime override (greater than 0 and at most 1). Ignores historical uptime — useful for what-if analysis. Use `0.01` to approximate near-total downtime; `0` is rejected with `400 bad_request`. | -| `beta` | No | Ignored for standard API keys — the API derives timescale weighting from `r`. | +| `beta` | No | Not user-configurable — the API derives timescale weighting from `r`. | ### Limits diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 0438df8f..34ce73e4 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -20,7 +20,7 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative | Goal | Start here | | --- | --- | -| Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer) | +| Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer). Planned downtime during active rentals still needs [CLI/REST schedule maint](#scheduled-maintenance) — no in-console scheduler. | | Enable or update SLA via API | [Before you enable SLA](#before-you-enable-sla) → [API (for automation)](#api-for-automation) | | I list with CLI only (no SLA flags yet) | **Set Pricing → SLA** + **LIST** in the console, or REST `PUT /api/v0/machines/create_asks/` — SLA flags are **not** in `vastai list machine` yet | | Monitor settlement after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | @@ -526,7 +526,7 @@ This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/ra When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` (UTC day indices). +- **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` as UTC day indices (`day = floor(unix_epoch_seconds / 86400)`). Example: for `2026-07-24` UTC, `sday=eday=20658`. Prefer `last_days` when you do not need an absolute window. - **Fleet snapshot:** one request without `machid` returns all machines in `per_machine[]` for the window: ```bash diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 3c27f94f..e3f28613 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -1,6 +1,6 @@ -Schedule upcoming maint window +Schedule an upcoming maintenance window -This is a **host** command, used for managing machines you are renting out on Vast.ai. +This is a **host** command, used for managing machines you are renting out on Vast.ai. First time? Install the CLI via [CLI hello world](/cli/hello-world), then confirm with `vastai --help`. ## Usage @@ -23,7 +23,7 @@ vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_c - maintenance duration in hours + Maintenance duration in hours. Prefer whole hours for REST compatibility (OpenAPI `duration` is an integer). The CLI may accept fractional values (for example `0.5`). @@ -45,15 +45,17 @@ The same `schedule maint` command is used for both **planned** and **emergency** If SLA is enabled and you need planned downtime during an active rental, schedule at least 24 hours in advance. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ```bash -vastai schedule maint 8207 --sdate 1785549600 --duration 2 --maintenance_category software +# Replace MACHINE_ID; set --sdate to a future UTC epoch (≥24h ahead for planned credit review) +# Linux: date -u -d '2026-08-01 02:00:00' +%s +vastai schedule maint MACHINE_ID --sdate 1785549600 --duration 2 --maintenance_category software ``` ### Emergency or unplanned maintenance -If the machine must go offline without adequate notice, still run `schedule maint` to notify renters — but expect full SLA settlement exposure when SLA is enabled. +If the machine must go offline without adequate notice, still run `schedule maint` to notify renters — but expect full SLA settlement exposure when SLA is enabled. Use the current UTC epoch for `--sdate` and an integer `--duration` (hours): ```bash -vastai schedule maint 8207 --sdate 1677562671 --duration 0.5 --maintenance_category power +vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` ## Examples From 2fd7b7f71cdd82c2b57bff3007528765510eed6d Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 14:18:08 -0700 Subject: [PATCH 023/250] docs(sla): address doc-review consensus (cycle 7) Strip CMS frontmatter, align storage/beta/OpenAPI notes, and fix create-instance error codes for integrators. Co-authored-by: Cursor --- api-reference/openapi.yaml | 6 +++--- api-reference/openapi/yaml/sla_backtest.yaml | 5 ++++- cli/reference/search-offers.mdx | 3 ++- guides/instances/choosing/sla-coverage.mdx | 19 +++++++++++++++---- host/hosting-overview.mdx | 6 +++--- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 795d97a0..a589de1c 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9312,9 +9312,9 @@ paths: type: number format: float default: 0.5 - description: "Timescale mix override. For non-admins this is ignored \u2014\ - \ the API derives beta from r (same default a client targeting r would get).\ - \ Admins may override for analysis." + description: "Timescale mix used in settlement simulation. Not user-configurable\ + \ for host API keys \u2014\nthe API derives weighting from `r` (recent vs\ + \ longer-term uptime). Omit this parameter.\n" responses: '200': description: Successful response diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index eab06390..162264cd 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -71,7 +71,10 @@ paths: type: number format: float default: 0.5 - description: Timescale mix override. For non-admins this is ignored — the API derives beta from r (same default a client targeting r would get). Admins may override for analysis. + description: | + Timescale mix used in settlement simulation. Not user-configurable for host API keys — + the API derives weighting from `r` (recent vs longer-term uptime). Omit this parameter. + responses: '200': description: Successful response diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 16f47c49..d048b8ae 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -85,7 +85,8 @@ vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=Fal # Search pricing only — target_reliability here quotes dph_total; it does not enable SLA on rent. # To cover a rental: console Search target, or REST create-instance with target_reliability. # vastai create instance does not support SLA yet. -vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --order dph_total +# Always set --storage explicitly (CLI default 5 GiB; REST search default 8 GB) when comparing dph_total. +vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total # datacenter GPUs with minimum compute capability and TFLOPs vastai search offers 'compute_cap > 610 total_flops > 5 datacenter=True' diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index a07c4475..2d3507b7 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -14,6 +14,14 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing `target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Searching with `target_reliability` only affects quoted pricing — it does **not** enable SLA on the contract unless you pass the same value at create-instance via **REST** or the **web console**. + +## Choose your path + +| Goal | Start here | +| --- | --- | +| Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | +| Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | +| Automate search → rent → verify | [API automation](#api-automation) (REST; CLI cannot rent with SLA yet) | @@ -68,7 +76,7 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). 2. In Search filters (left filter bar), set **Reliability target** to your desired coverage level — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. -3. Optionally filter to SLA-enabled offers (`has_sla` / SLA-enabled control) if available — separate from **Reliability target**. +3. Optionally narrow to host SLA listings with an SLA-enabled / `has_sla` filter if shown. That filter only restricts which offers appear — it does **not** replace setting **Reliability target**. If you do not see a separate SLA toggle, set Reliability target and confirm the SLA charge line before rent. 4. Before you click **RENT**, confirm the price breakdown shows an **SLA charge** line. No SLA charge means no SLA coverage for that rental. 5. Rent as usual. Your target is locked at rent time. @@ -164,8 +172,9 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe | --- | --- | --- | | Target on a non-SLA offer | HTTP 400 `invalid_args` | Search with `has_sla=true`; confirm `expected_reliability` | | Target out of range / invalid | HTTP 400 `invalid_args` | Use `0 < target_reliability < 1`; stay at or below a realistic host claim | -| Offer gone / not rentable | HTTP 404/410 `no_such_ask` | Re-search and rent a current offer ID | -| Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage, then rent again | +| Offer unavailable / stale | HTTP 404 `invalid_args` (check `msg` for `no_such_ask`) | Re-search and rent a current offer ID | +| Offer no longer exists | HTTP 410 `no_such_ask` | Re-search for a new offer ID | +| Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | Hold `allocated_storage` / `--storage` constant when comparing `dph_total` across runs or between CLI and REST. @@ -237,7 +246,9 @@ Production settlement uses the multi-window reliability blend described above, n 2. Open **price details** (or the instance billing panel) and confirm an **SLA charge** line is present. 3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. If you do not see a target or SLA charge, you likely rented without SLA coverage. -### API / CLI +### API integrators + +CLI can search with `target_reliability` but cannot enable or verify SLA on contracts today. Use the web console or REST for rent and post-rent verification. Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 92002c1f..13240462 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -1,8 +1,6 @@ --- title: "Hosting Overview" -slug: "xP4AEPJl2F6woPGcD7EWl" -createdAt: "Tue Jan 14 2025 01:09:17 GMT+0000 (Coordinated Universal Time)" -updatedAt: "Fri Jul 11 2025 22:44:42 GMT+0000 (Coordinated Universal Time)" +description: "Set up hosting on Vast.ai: accounts, machines, offers, maintenance, and common questions." "canonical": "/host/hosting-overview" --- @@ -231,6 +229,8 @@ You can then look at your [instance tab](https://cloud.vast.ai/instances/) to ma ## Maintenance +**Prerequisite:** Planned maintenance during active SLA rentals requires the [Vast CLI](/cli/hello-world) or REST — there is no in-console scheduler. Install the CLI before you enable SLA — see [Before you enable SLA](/host/sla-offers#before-you-enable-sla). + Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. Unlisting the offer prevents new rentals but does not end existing ones. If you have active contracts, you can set the offer end date to match the latest rental end date so new clients rent instances that end together. Once that date is reached, unlist and perform maintenance. From f20583a0ac17a52c8c014102bce65cdc2d4c7c20 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 24 Jul 2026 14:23:06 -0700 Subject: [PATCH 024/250] docs(sla): address doc-review consensus (cycle 8) Document SLA create-instance error modes in OpenAPI and un-nest client Choose your path from the opt-in Note. Co-authored-by: Cursor --- api-reference/openapi.yaml | 19 ++++++++++++++++++- .../openapi/yaml/create_instance.yaml | 8 +++++++- guides/instances/choosing/sla-coverage.mdx | 4 ++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index a589de1c..03c0eb8b 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1662,6 +1662,14 @@ paths: Use the same value you used in search when comparing `dph_total`. + Common failures: `invalid_args` when the offer has no SLA or the + target is out of range; + + `invalid_price` when the quote is stale relative to search (re-search + with matching storage + + and `target_reliability`, then rent again). See [SLA Coverage](/guides/instances/choosing/sla-coverage). + ' runtype: type: string @@ -1807,7 +1815,16 @@ paths: description: ID of the newly created instance contract example: 1234568 '400': - description: Bad Request + description: 'Bad Request. Includes invalid or out-of-range `target_reliability`, + renting with SLA on a non-SLA + + offer, SSH key requirements, and `invalid_price` when the create request + does not match a fresh + + search quote (re-search with the same `target_reliability` and disk/storage, + then retry). + + ' content: application/json: schema: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 1306ca66..0324cf0d 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -72,6 +72,9 @@ paths: Client SLA coverage target (greater than 0 and less than 1). When set on an SLA-enabled offer (`sla_r_claim > 0`), locks SLA terms on the new contract. Omit or set to 0 for a non-SLA rental. Use the same value you used in search when comparing `dph_total`. + Common failures: `invalid_args` when the offer has no SLA or the target is out of range; + `invalid_price` when the quote is stale relative to search (re-search with matching storage + and `target_reliability`, then rent again). See [SLA Coverage](/guides/instances/choosing/sla-coverage). runtype: type: string description: | @@ -190,7 +193,10 @@ paths: description: ID of the newly created instance contract example: 1234568 '400': - description: Bad Request + description: | + Bad Request. Includes invalid or out-of-range `target_reliability`, renting with SLA on a non-SLA + offer, SSH key requirements, and `invalid_price` when the create request does not match a fresh + search quote (re-search with the same `target_reliability` and disk/storage, then retry). content: application/json: schema: diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 2d3507b7..26b8dcba 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -10,6 +10,7 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing **SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via the **REST API**, pass `target_reliability` on **create-instance** (`PUT /api/v0/asks/{id}/`). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. + `target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Searching with `target_reliability` only affects quoted pricing — it does **not** enable SLA on the contract unless you pass the same value at create-instance via **REST** or the **web console**. @@ -22,7 +23,6 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | | Automate search → rent → verify | [API automation](#api-automation) (REST; CLI cannot rent with SLA yet) | - SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). @@ -38,7 +38,7 @@ SLA is a **contractual, per-rental** reliability guarantee with automatic daily For SLA-covered on-demand contracts: -- You are charged for **compute and the SLA charge** for the rental day, including periods when the instance is unavailable. +- You are charged for **compute, storage, and the SLA charge** for the rental day, including periods when the instance is unavailable. - Offline time is tracked as an outage in reliability measurements. - If you qualify for compensation, a **settlement credit** posts after daily settlement (UTC) — typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. From 55f817a5a7228598deb3e8651d8f932ca23b5f2f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:18:45 -0700 Subject: [PATCH 025/250] docs(sla): clarify hosts do not set beta; fix navbar FAQ URL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite sla_max_beta as an optional client-β cap and use an absolute FAQ href for Mintlify. Co-authored-by: Cursor --- api-reference/openapi.yaml | 16 ++++++++-------- api-reference/openapi/yaml/list_machine.yaml | 6 ++++-- api-reference/openapi/yaml/show_machines.yaml | 4 +++- docs.json | 2 +- host/sla-offers.mdx | 6 ++++-- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 03c0eb8b..afb572da 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4608,13 +4608,11 @@ paths: sla_max_beta: type: number format: float - description: 'Optional term capping how path-dependent a client''s - timescale mix can be. - - Must be in (0, 1) and at least the default beta derived at your - claim. - - ' + description: "Optional ask term capping the client-derived timescale\ + \ mix (\u03B2) this offer accepts.\nHosts do not set \u03B2 \u2014\ + \ the platform derives \u03B2 from the client's target_reliability\ + \ at rent.\nLeave unset for uncapped. When set, must be in (0,\ + \ 1) and at least the default beta\nderived at your claim.\n" sla_r_target: type: number format: float @@ -9000,7 +8998,9 @@ paths: description: SLA confidence spread around the claim. sla_max_beta: type: number - description: Optional cap on client timescale mix (beta). + description: "Optional cap on the client-derived timescale\ + \ mix (\u03B2) this ask accepts.\nHosts do not set \u03B2\ + ; leave unset for uncapped.\n" example: machines: - id: '12345' diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index c23e8eed..5d41abcb 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -82,8 +82,10 @@ paths: type: number format: float description: | - Optional term capping how path-dependent a client's timescale mix can be. - Must be in (0, 1) and at least the default beta derived at your claim. + Optional ask term capping the client-derived timescale mix (β) this offer accepts. + Hosts do not set β — the platform derives β from the client's target_reliability at rent. + Leave unset for uncapped. When set, must be in (0, 1) and at least the default beta + derived at your claim. sla_r_target: type: number format: float diff --git a/api-reference/openapi/yaml/show_machines.yaml b/api-reference/openapi/yaml/show_machines.yaml index 761bd7a9..09d61837 100644 --- a/api-reference/openapi/yaml/show_machines.yaml +++ b/api-reference/openapi/yaml/show_machines.yaml @@ -56,7 +56,9 @@ paths: description: SLA confidence spread around the claim. sla_max_beta: type: number - description: Optional cap on client timescale mix (beta). + description: | + Optional cap on the client-derived timescale mix (β) this ask accepts. + Hosts do not set β; leave unset for uncapped. example: machines: - id: "12345" diff --git a/docs.json b/docs.json index 89bb9457..8387f515 100644 --- a/docs.json +++ b/docs.json @@ -862,7 +862,7 @@ "links": [ { "label": "FAQ", - "href": "/guides/reference/faq" + "href": "https://docs.vast.ai/guides/reference/faq" }, { "label": "Discord", diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 34ce73e4..83c6a58f 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -106,7 +106,9 @@ When you list or update a machine, set SLA fields via the host console or `PUT / ### Advanced: `sla_max_beta` (optional) -Omit unless Vast support directs you. Optional ask term `sla_max_beta` limits how path-dependent a client's timescale mix can be for long-running contracts. Must be in `(0, 1)` and at least the default β derived at your claim. Most hosts should leave it unset. +Hosts do **not** set β (timescale mix). The platform derives β from the client's `target_reliability` at rent time. + +`sla_max_beta` is an optional ask **term**: a ceiling on how high a client-derived β this offer will accept (it caps collateral-lock duration for long-running contracts). Leave it unset for an uncapped offer. If you set it, it must be in `(0, 1)` and at least the default β derived at your claim — otherwise listing is rejected. Omit unless Vast support directs you. **`sla_r_target` is not host-settable.** If you send `sla_r_target` or legacy `sla_reliability` on `create_asks/`, they are **ignored**. Clients supply their coverage target at search/rent time (`target_reliability`). Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x` — they use different scales. Use the mapping table on the [backtester page](/host/sla-backtester#confidence-values-p). @@ -151,7 +153,7 @@ Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.9999**. Exactly `1.0` is rejected. - When claim is positive, `sla_sigma_x` must be positive and at most `3.0` (defaults to `0.5` if omitted). -- Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your claim. +- Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your claim. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. If listing is rejected with `error: "invalid_sla_params"`, check the `msg` field against the rules above. Other SLA listing errors include `sla_not_approved` and `sla_daemon_outdated`. From ac738178a48d65f3ea07b326bd200d5b7b4ff6fd Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:24:27 -0700 Subject: [PATCH 026/250] docs(sla): address doc-review consensus (cycle 1) Fix stale end_date examples, elevate CLI search-vs-rent SLA warnings, and soften sla_max_beta wording. Co-authored-by: Cursor --- api-reference/openapi.yaml | 15 ++++++------ api-reference/openapi/yaml/list_machine.yaml | 8 +++---- api-reference/openapi/yaml/show_machines.yaml | 4 ++-- cli/reference/search-offers.mdx | 5 ++++ guides/instances/choosing/sla-coverage.mdx | 6 ++++- host/hosting-overview.mdx | 10 +++++++- host/sla-offers.mdx | 24 +++++++++++-------- snippets/host/cli/list-machine.mdx | 8 +++---- snippets/host/cli/schedule-maint.mdx | 4 ++-- snippets/host/sdk/list-machine.mdx | 4 +++- 10 files changed, 56 insertions(+), 32 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index afb572da..f97b8ccf 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4608,11 +4608,12 @@ paths: sla_max_beta: type: number format: float - description: "Optional ask term capping the client-derived timescale\ - \ mix (\u03B2) this offer accepts.\nHosts do not set \u03B2 \u2014\ - \ the platform derives \u03B2 from the client's target_reliability\ - \ at rent.\nLeave unset for uncapped. When set, must be in (0,\ - \ 1) and at least the default beta\nderived at your claim.\n" + description: "Optional ask term capping how aggressively long-running\ + \ contracts may weight recent\nuptime versus longer history in\ + \ settlement. Hosts do not set \u03B2 \u2014 the platform derives\n\ + \u03B2 from the client's target_reliability at rent. Leave unset\ + \ for uncapped. When set,\nmust be in (0, 1) and at least the\ + \ default beta derived at your claim.\n" sla_r_target: type: number format: float @@ -8998,8 +8999,8 @@ paths: description: SLA confidence spread around the claim. sla_max_beta: type: number - description: "Optional cap on the client-derived timescale\ - \ mix (\u03B2) this ask accepts.\nHosts do not set \u03B2\ + description: "Optional cap on client-derived \u03B2 for\ + \ this ask (support-directed). Hosts do not\nset \u03B2\ ; leave unset for uncapped.\n" example: machines: diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 5d41abcb..52d59d7d 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -82,10 +82,10 @@ paths: type: number format: float description: | - Optional ask term capping the client-derived timescale mix (β) this offer accepts. - Hosts do not set β — the platform derives β from the client's target_reliability at rent. - Leave unset for uncapped. When set, must be in (0, 1) and at least the default beta - derived at your claim. + Optional ask term capping how aggressively long-running contracts may weight recent + uptime versus longer history in settlement. Hosts do not set β — the platform derives + β from the client's target_reliability at rent. Leave unset for uncapped. When set, + must be in (0, 1) and at least the default beta derived at your claim. sla_r_target: type: number format: float diff --git a/api-reference/openapi/yaml/show_machines.yaml b/api-reference/openapi/yaml/show_machines.yaml index 09d61837..d0d56e5e 100644 --- a/api-reference/openapi/yaml/show_machines.yaml +++ b/api-reference/openapi/yaml/show_machines.yaml @@ -57,8 +57,8 @@ paths: sla_max_beta: type: number description: | - Optional cap on the client-derived timescale mix (β) this ask accepts. - Hosts do not set β; leave unset for uncapped. + Optional cap on client-derived β for this ask (support-directed). Hosts do not + set β; leave unset for uncapped. example: machines: - id: "12345" diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index d048b8ae..832deade 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -87,6 +87,11 @@ vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=Fal # vastai create instance does not support SLA yet. # Always set --storage explicitly (CLI default 5 GiB; REST search default 8 GB) when comparing dph_total. vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total +``` + + +**Next step:** Search pricing does not enable SLA. To rent with coverage, use the web console or REST create-instance — see [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation). `vastai create instance` does not support SLA yet. + # datacenter GPUs with minimum compute capability and TFLOPs vastai search offers 'compute_cap > 610 total_flops > 5 datacenter=True' diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 26b8dcba..d15caeb0 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -56,7 +56,7 @@ total ≈ GPU + storage + bandwidth + SLA charge | --- | --- | | Your reliability target | Higher target → higher SLA charge | | Host SLA claim | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher claim → lower SLA charge at a given target | -| Host confidence | Host-side pricing setting that affects SLA charge size. **Not shown on offer cards** — compare offers using `dph_total` or the SLA charge line in the price breakdown | +| Host confidence | Host-side pricing setting that affects SLA charge size. **You do not set this** — the host chooses it, and it is **not shown on offer cards**. Compare offers using `dph_total` or the SLA charge line in the price breakdown | **Rule of thumb:** pick a target **at or below** the host's claim for the best value. Asking for 99% coverage on a host who only claims 95% costs much more than asking for 95% on a host who claims 99%. @@ -72,6 +72,10 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 ## Finding SLA offers + +**CLI-only renters:** You can search and price SLA offers from the CLI (`target_reliability` in `vastai search offers`), but SLA coverage is enabled only at create-instance time via the **web console** or **REST API** (`target_reliability` on `PUT /api/v0/asks/{id}/`). `vastai create instance` does not support SLA yet. See [API automation](#api-automation). + + ### In the web console 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 13240462..52fcf260 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -5,6 +5,10 @@ description: "Set up hosting on Vast.ai: accounts, machines, offers, maintenance --- + +**Looking to rent GPUs?** See [Finding & Renting Instances](/guides/instances/choosing/find-and-rent) and [SLA Coverage](/guides/instances/choosing/sla-coverage). + + Vast is a GPU marketplace. Hosts sell GPU resources on the marketplace. Hosts are responsible for: - Setup: installing Ubuntu, creating disk partitions, installing NVIDIA drivers, opening network ports on the router and installing the Vast hosting software. @@ -36,7 +40,7 @@ Clients have high expectations coming from AWS or GCP. As a host, plan to offer ## Offers and Rental Contracts -Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). +Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). SLA claim and confidence require **Set Pricing → SLA** in the console or REST `create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). The main offer parameters include: @@ -225,6 +229,10 @@ vastai create instance --image pytorch/pytorch:latest --jupyter --direct -- Use `./vastai` instead of `vastai` when running from the install directory. + +CLI self-tests create **non-SLA** rentals (`vastai create instance` does not accept `target_reliability`). To test SLA contract terms on your own offer, use the console with a reliability target or REST create-instance with `target_reliability` — see [SLA Coverage](/guides/instances/choosing/sla-coverage). + + You can then look at your [instance tab](https://cloud.vast.ai/instances/) to make sure that pytorch loaded correctly along with jupyter and ssh. Click on the \<\_ button to get the ssh command to connect to the instance. Test the direct ssh command. Click on the open button to test jupyter. If the button is stuck "connecting" then there is most likely a problem with the port configuration on the router in front of the machine. Once finished, destroy the instance. ## Maintenance diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 83c6a58f..16fb9b84 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -106,9 +106,9 @@ When you list or update a machine, set SLA fields via the host console or `PUT / ### Advanced: `sla_max_beta` (optional) -Hosts do **not** set β (timescale mix). The platform derives β from the client's `target_reliability` at rent time. +**Support-only — omit unless Vast support directs you.** Hosts do **not** set β (timescale mix). The platform derives β from the client's `target_reliability` at rent time. -`sla_max_beta` is an optional ask **term**: a ceiling on how high a client-derived β this offer will accept (it caps collateral-lock duration for long-running contracts). Leave it unset for an uncapped offer. If you set it, it must be in `(0, 1)` and at least the default β derived at your claim — otherwise listing is rejected. Omit unless Vast support directs you. +`sla_max_beta` is an optional ask term that caps how aggressively long-running contracts may weight recent uptime versus longer history in settlement. Leave it unset for an uncapped offer. If you set it, it must be in `(0, 1)` and at least the default β derived at your claim — otherwise listing is rejected. **`sla_r_target` is not host-settable.** If you send `sla_r_target` or legacy `sla_reliability` on `create_asks/`, they are **ignored**. Clients supply their coverage target at search/rent time (`target_reliability`). Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x` — they use different scales. Use the mapping table on the [backtester page](/host/sla-backtester#confidence-values-p). @@ -139,11 +139,13 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r **This only changes how SLA charges are priced — it does not change how reliability is measured or what credit you owe when a client's target is missed.** Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. -| Guidance | Pricing effect | `sla_sigma_x` | Risk if you miss claim | +| Console label | API `sla_sigma_x` | Backtester `p` | Pricing effect | | --- | --- | --- | --- | -| Tight | Lowest client SLA charges at a given target | `0.2` | Highest charge sensitivity | -| Normal (default) | Balanced | `0.5` | Moderate | -| Wide | Highest client SLA charges at a given target | `1.0` | Lowest charge sensitivity | +| Tight | `0.2` | ~0.83 | Lowest client SLA charges at a given target | +| Normal (default) | `0.5` | ~0.6667 | Balanced | +| Wide | `1.0` | ~0.50 | Highest client SLA charges at a given target | + +**Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). Higher confidence (tighter spread) → lower client SLA charges, but less room for reliability to slip before settlement credits grow. @@ -231,11 +233,11 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ "price_gpu": 3.50, "sla_r_claim": 0.99, "sla_sigma_x": 0.5, - "end_date": 1735689600 + "end_date": 1893456000 }' ``` -Set `end_date` so the offer does not stay open indefinitely — especially important for SLA commitments. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2025-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2025-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`. +Replace `end_date` with a **future** Unix timestamp — past dates expire the offer immediately (example `1893456000` = 2030-01-01 00:00 UTC). Set `end_date` so the offer does not stay open indefinitely — especially important for SLA commitments. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`. Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric payout risk. See [Offer End Date](/host/hosting-overview#offer-end-date). @@ -245,7 +247,7 @@ Minimal example: { "machine": 12345, "price_gpu": 3.50, - "end_date": 1735689600, + "end_date": 1893456000, "sla_r_claim": 0.99, "sla_sigma_x": 0.5 } @@ -267,7 +269,9 @@ Machine `id` may be a string in raw JSON. The response is wrapped in a `machines Then `PUT /api/v0/machines/create_asks/` with merged fields. -### Fleet listing workflow +### Fleet listing workflow (advanced — fleet operators only) + +Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding claim/confidence. Skip unlisted machines. For multiple machines, loop sequentially — do not parallelize without backoff: diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index d935e4ad..36bd93b5 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -69,15 +69,15 @@ vastai list machine ID [options] ## Description Performs the same action as pressing the "LIST" button on the site https://cloud.vast.ai/host/machines. -On the end date the listing will expire and your machine will unlist. However, any existing rental contracts will still remain until ended by their owners. +On the end date, the listing will expire and your machine will unlist. However, any existing rental contracts will still remain until ended by their owners. Once you list your machine and it is rented, it is extremely important that you don't interfere with the machine in any way. -If your machine has an active rental contract and then goes offline, crashes, or has performance problems, this could permanently lower your reliability rating. -We strongly recommend you test the machine first and only list when ready. +If your machine has an active rental contract and then goes offline, crashes, or has performance problems, this can lower your marketplace reliability score (it recovers with continued good uptime — see [Hosting overview](/host/hosting-overview#why-did-the-reliability-on-my-machine-decrease)). +We strongly recommend you test the machine first and only list when ready. Always set an offer end date (`-e`) for SLA listings — see [Offer End Date](/host/hosting-overview#offer-end-date) and [SLA Offers](/host/sla-offers). ## Examples ```bash -vastai list machine +vastai list machine -g 3.50 -e "01/01/2030" ``` ## Global Options diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index e3f28613..8b0f2858 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -8,12 +8,12 @@ Schedule an upcoming maintenance window vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY] ``` -`schedule maintenance` is an alias for `schedule maint` if your CLI build supports both spellings. Prefer `maint`. +`schedule maintenance` is an alias for `schedule maint` if your CLI build supports both spellings. Prefer `maint`. Requires `machine_write` on scoped API keys — see [Permissions](/api-reference/permissions). ## Arguments - id of machine to schedule maintenance for + ID of the machine to schedule maintenance for. ## Options diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 5258f72d..e1143f00 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -67,6 +67,8 @@ VastAI.list_machine( from vastai import VastAI client = VastAI(api_key="YOUR_API_KEY") -result = client.list_machine(id=12345, price_gpu=3.50) +# Base listing only — for SLA, use the console or REST create_asks after list_machine() +# see SLA Offers → API (for automation): /host/sla-offers#api-for-automation +result = client.list_machine(id=12345, price_gpu=3.50, end_date="01/01/2030") print(result) ``` From d57580fc19accb030397d5db0d808e8738817ec3 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:29:03 -0700 Subject: [PATCH 027/250] docs(sla): address doc-review consensus (cycle 2) Repair search-offers examples fence, split backtester 400 error rows, and name show-instances verify path. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 9 ++++----- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-backtester.mdx | 5 ++++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 832deade..ccb8ed5d 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -87,11 +87,6 @@ vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=Fal # vastai create instance does not support SLA yet. # Always set --storage explicitly (CLI default 5 GiB; REST search default 8 GB) when comparing dph_total. vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total -``` - - -**Next step:** Search pricing does not enable SLA. To rent with coverage, use the web console or REST create-instance — see [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation). `vastai create instance` does not support SLA yet. - # datacenter GPUs with minimum compute capability and TFLOPs vastai search offers 'compute_cap > 610 total_flops > 5 datacenter=True' @@ -112,6 +107,10 @@ vastai search offers 'reliability > 0.99 num_gpus>=4 verified=False rented=any' vastai search offers 'cpu_arch=arm64' ``` + +**Next step:** Search pricing does not enable SLA. To rent with coverage, use the web console or REST create-instance — see [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation). `vastai create instance` does not support SLA yet. + + ## Available Fields | Field | Type | Description | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d15caeb0..8133d2f5 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -170,7 +170,7 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and preferably `instance_read` (verify show-instances). See [Authentication](/api-reference/authentication) and [Permissions](/api-reference/permissions). -**3. Verify** via show-instances: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. +**3. Verify** via `GET /api/v1/instances/` (show-instances / `vastai show instances`): confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. | Symptom | Typical response | What to do | | --- | --- | --- | diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 6ddcc8c1..3d495b85 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -264,7 +264,10 @@ Higher confidence (higher `p`) → tighter spread → lower SLA charges for clie | HTTP | `error` / shape | Cause | | --- | --- | --- | -| 400 | `invalid_range`, `range_too_large`, `bad_request`, `invalid_params` | Invalid query parameters or simulation failure | +| 400 | `invalid_range` | Date window invalid | +| 400 | `range_too_large` | Window exceeds the maximum span | +| 400 | `bad_request` | Out-of-range `r`, `p`, or date parameters | +| 400 | `invalid_params` | Simulation math failure after validation (check claim/confidence inputs) | | 403 | `not_owner` | Machine belongs to another host | | 404 | `machine_not_found` | Invalid `machine_id` | | 429 | *(rate limited)* | Too many requests — retry with backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | From 25de5dabe190d53f879dbaf607e75cb71d68dc65 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:33:34 -0700 Subject: [PATCH 028/250] docs(sla): address doc-review consensus (cycle 3) Resolve CLI verify contradiction, document instances pagination and search order/limit for SLA automation. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 5 +++-- host/hosting-overview.mdx | 8 +++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index ccb8ed5d..b850613a 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -48,7 +48,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] - + Maximum number of offers to return. Prefer an explicit limit when comparing SLA-inclusive `dph_total` results; combine with `--order` / `-o` as needed. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 8133d2f5..09c92b3a 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -147,6 +147,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ "limit": 20, "type": "ondemand", "allocated_storage": 50, + "order": [["dph_total", "asc"]], "target_reliability": {"eq": 0.95}, "has_sla": {"eq": true}, "expected_reliability": {"gte": 0.99} @@ -170,7 +171,7 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and preferably `instance_read` (verify show-instances). See [Authentication](/api-reference/authentication) and [Permissions](/api-reference/permissions). -**3. Verify** via `GET /api/v1/instances/` (show-instances / `vastai show instances`): confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. +**3. Verify** via `GET /api/v1/instances/` or `vastai show instances --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. `GET /api/v1/instances/` returns at most 25 instances per request — paginate with `next_token` until exhausted if you manage many rentals. | Symptom | Typical response | What to do | | --- | --- | --- | @@ -252,7 +253,7 @@ Production settlement uses the multi-window reliability blend described above, n ### API integrators -CLI can search with `target_reliability` but cannot enable or verify SLA on contracts today. Use the web console or REST for rent and post-rent verification. +CLI can search with `target_reliability` and can **read** post-rent SLA fields via `vastai show instances --raw`, but cannot **enable** SLA at create-instance time (`vastai create instance` has no `target_reliability`). Use the web console or REST to rent with SLA. Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 52fcf260..31a8ce39 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -230,7 +230,13 @@ vastai create instance --image pytorch/pytorch:latest --jupyter --direct -- Use `./vastai` instead of `vastai` when running from the install directory. -CLI self-tests create **non-SLA** rentals (`vastai create instance` does not accept `target_reliability`). To test SLA contract terms on your own offer, use the console with a reliability target or REST create-instance with `target_reliability` — see [SLA Coverage](/guides/instances/choosing/sla-coverage). +CLI self-tests create **non-SLA** rentals (`vastai create instance` does not accept `target_reliability`). To test SLA contract terms on your own offer: + +1. Create a separate client account (see above), or use REST from that account. +2. In the console Search filters, set a **Reliability target**, rent your own offer, and confirm an **SLA charge** line before continuing — or `PUT /api/v0/asks/{id}/` with `target_reliability`. +3. Destroy the test instance when done. + +See [SLA Coverage](/guides/instances/choosing/sla-coverage) for renter-side details. You can then look at your [instance tab](https://cloud.vast.ai/instances/) to make sure that pytorch loaded correctly along with jupyter and ssh. Click on the \<\_ button to get the ssh command to connect to the instance. Test the direct ssh command. Click on the open button to test jupyter. If the button is stuck "connecting" then there is most likely a problem with the port configuration on the router in front of the machine. Once finished, destroy the instance. From 8dc39e88d724a8a67793117b6f7b8fa1a68a86fa Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:33:39 -0700 Subject: [PATCH 029/250] docs(sla): fix weigh wording in sla_max_beta Co-authored-by: Cursor --- host/sla-offers.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 16fb9b84..26f4a59f 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -108,7 +108,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / **Support-only — omit unless Vast support directs you.** Hosts do **not** set β (timescale mix). The platform derives β from the client's `target_reliability` at rent time. -`sla_max_beta` is an optional ask term that caps how aggressively long-running contracts may weight recent uptime versus longer history in settlement. Leave it unset for an uncapped offer. If you set it, it must be in `(0, 1)` and at least the default β derived at your claim — otherwise listing is rejected. +`sla_max_beta` is an optional ask term that caps how aggressively long-running contracts may weigh recent uptime versus longer history in settlement. Leave it unset for an uncapped offer. If you set it, it must be in `(0, 1)` and at least the default β derived at your claim — otherwise listing is rejected. **`sla_r_target` is not host-settable.** If you send `sla_r_target` or legacy `sla_reliability` on `create_asks/`, they are **ignored**. Clients supply their coverage target at search/rent time (`target_reliability`). Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x` — they use different scales. Use the mapping table on the [backtester page](/host/sla-backtester#confidence-values-p). From 07973e8a5f62a1d036036896df9b129a96a24683 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:39:58 -0700 Subject: [PATCH 030/250] docs(sla): address doc-review consensus (cycle 4) Fix maint scheduling examples, dph_total/bandwidth wording, after_token pagination, and CLI rent decision rule. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 11 +++----- guides/instances/choosing/find-and-rent.mdx | 4 +-- guides/instances/choosing/sla-coverage.mdx | 31 +++++++++------------ host/sla-offers.mdx | 11 +++++--- snippets/host/cli/list-machine.mdx | 4 +-- snippets/host/cli/schedule-maint.mdx | 8 ++++-- snippets/host/sdk/list-machine.mdx | 4 +-- 7 files changed, 33 insertions(+), 40 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index b850613a..b002255a 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -81,11 +81,8 @@ bool = True | False # reliable single RTX 3090, no conflicts with stopped instances vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=False' -# SLA offers: host claim ≥ 99%, your coverage target 95% (see SLA Coverage) -# Search pricing only — target_reliability here quotes dph_total; it does not enable SLA on rent. -# To cover a rental: console Search target, or REST create-instance with target_reliability. -# vastai create instance does not support SLA yet. -# Always set --storage explicitly (CLI default 5 GiB; REST search default 8 GB) when comparing dph_total. +# SLA search quote (enable coverage at rent via console/REST — see SLA Coverage) +# Always set --storage explicitly when comparing dph_total (CLI default 5 GiB ≠ REST 8 GB). vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total # datacenter GPUs with minimum compute capability and TFLOPs @@ -108,7 +105,7 @@ vastai search offers 'cpu_arch=arm64' ``` -**Next step:** Search pricing does not enable SLA. To rent with coverage, use the web console or REST create-instance — see [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation). `vastai create instance` does not support SLA yet. +**Next step:** Search quotes SLA pricing only — see [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers) to rent with coverage (console or REST). ## Available Fields @@ -159,7 +156,7 @@ vastai search offers 'cpu_arch=arm64' | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability claim on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | -| `target_reliability` | float | your desired SLA coverage level (greater than 0 and less than 1); drives SLA charge in `dph_total` for **search quotes only**. Pass the same value at create-instance via console or REST to enable coverage — `vastai create instance` does not support SLA yet (see [SLA Coverage](/guides/instances/choosing/sla-coverage)) | +| `target_reliability` | float | desired SLA coverage (0–1 exclusive); prices `dph_total` in search only — see [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers) to enable at rent | | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index b4b998d7..e03e0f7c 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -58,13 +58,13 @@ All stats shown are the portion of the total machine rented. - Max Duration: The maximum length of a rental contract on this machine - Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host SLA claim. - Rental Option: RENT button -- **SLA (optional):** Available on **on-demand** rentals only. Set a **reliability target** in Search before clicking **RENT** to opt in — see [SLA Coverage](/guides/instances/choosing/sla-coverage). +- **SLA (optional):** Available on **on-demand** rentals only. Set a **reliability target** in Search, then confirm the price breakdown includes an **SLA charge** line before clicking **RENT** — see [SLA Coverage](/guides/instances/choosing/sla-coverage). ## Instance Disk Size The storage slider is both a search filter and a parameter input which determines the storage allocation size - it's important to size this correctly before creating any instance. -When the instance is created, the disk size is set and cannot be modified. It is important to estimate how much disk you will need and then to move the slider to the desired disk size. The default disk size for an instance is 10GB. Use the slider to allocate more or less, taking into consideration that providers charge for disk allocation even when the instance is stopped. +When the instance is created, the disk size is set and cannot be modified. It is important to estimate how much disk you will need and then to move the slider to the desired disk size. The default disk size for an instance is 10GB. Use the slider to allocate more or less, taking into consideration that providers charge for disk allocation even when the instance is stopped. When comparing `dph_total` across the console, CLI, and REST search, hold storage constant — defaults differ (console 10 GB, REST search 8 GB, CLI `--storage` 5 GiB); see [SLA Coverage](/guides/instances/choosing/sla-coverage#api-automation). ![Diskspace](/images/find-and-rent-diskspace.webp) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 09c92b3a..516ea4a2 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -13,7 +13,7 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing -`target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Searching with `target_reliability` only affects quoted pricing — it does **not** enable SLA on the contract unless you pass the same value at create-instance via **REST** or the **web console**. +`target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Searching with a target only quotes pricing — use the **web console** or **REST** create-instance to enable coverage (see [Finding SLA offers](#finding-sla-offers)). ## Choose your path @@ -46,12 +46,14 @@ SLA is most useful for **long-running production workloads** where unexpected do ## How pricing works -Total hourly cost with SLA (`dph_total` = all-in dollars per hour in search): +Quoted hourly cost with SLA in search (`dph_total`): ``` -total ≈ GPU + storage + bandwidth + SLA charge +dph_total ≈ GPU + storage + SLA charge ``` +Bandwidth is billed separately from usage (`inet_*` rates) and is **not** included in `dph_total`. + | Factor | What it means for you | | --- | --- | | Your reliability target | Higher target → higher SLA charge | @@ -67,14 +69,13 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 | Cost component | Approx. rate | | --- | --- | | GPU compute | $3.50/hr | +| Storage (at search allocation) | ~$0.01/hr | | SLA charge | ~$0.008/hr | -| **Total (`dph_total`)** | ~$3.51/hr | +| **Total (`dph_total`)** | ~$3.52/hr | ## Finding SLA offers - -**CLI-only renters:** You can search and price SLA offers from the CLI (`target_reliability` in `vastai search offers`), but SLA coverage is enabled only at create-instance time via the **web console** or **REST API** (`target_reliability` on `PUT /api/v0/asks/{id}/`). `vastai create instance` does not support SLA yet. See [API automation](#api-automation). - +**Decision rule:** Search filters **quote** SLA pricing only. Coverage activates only when you rent via the **web console** (Reliability target set) or **REST** create-instance (`target_reliability` on `PUT /api/v0/asks/{id}/`). The CLI cannot enable SLA at rent time today — see [API automation](#api-automation) for the minimum REST rent path. ### In the web console @@ -129,15 +130,11 @@ When you search with an SLA target, reserved-instance discounts may not apply to | A | $3.50 | 99% | 95% | ~$0.008 | | B | $3.50 | 95% | 95% | much higher | -Always compare **`dph_total`**, not just GPU price, when SLA matters. Search ranking also accounts for SLA cost. +Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `dph_total` to compare total quoted cost. ### API automation - -SLA coverage is locked at **create-instance** time via `target_reliability` on `PUT /api/v0/asks/{id}/` (REST). Searching with a target only prices offers. The published CLI/SDK create-instance path does **not** accept `target_reliability` yet — use REST or the console to rent with SLA. - - -**1. Search** (prices `dph_total` at your target — include storage explicitly; REST defaults to 8 GB, CLI `--storage` defaults to 5 GiB): +**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable): ```bash curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ @@ -171,7 +168,7 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and preferably `instance_read` (verify show-instances). See [Authentication](/api-reference/authentication) and [Permissions](/api-reference/permissions). -**3. Verify** via `GET /api/v1/instances/` or `vastai show instances --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. `GET /api/v1/instances/` returns at most 25 instances per request — paginate with `next_token` until exhausted if you manage many rentals. +**3. Verify** via `GET /api/v1/instances/` or `vastai show instances --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. `GET /api/v1/instances/` returns at most 25 instances per request — paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. | Symptom | Typical response | What to do | | --- | --- | --- | @@ -181,7 +178,7 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe | Offer no longer exists | HTTP 410 `no_such_ask` | Re-search for a new offer ID | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | -Hold `allocated_storage` / `--storage` constant when comparing `dph_total` across runs or between CLI and REST. +Hold storage constant when comparing `dph_total`: console Instance Disk Size defaults to **10 GB**, REST search `allocated_storage` defaults to **8 GB**, and CLI `--storage` defaults to **5 GiB**. Mismatched defaults make the same offer look differently priced across tools. ## What happens after you rent @@ -253,9 +250,7 @@ Production settlement uses the multi-window reliability blend described above, n ### API integrators -CLI can search with `target_reliability` and can **read** post-rent SLA fields via `vastai show instances --raw`, but cannot **enable** SLA at create-instance time (`vastai create instance` has no `target_reliability`). Use the web console or REST to rent with SLA. - -Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. +Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. (CLI can **read** these fields via `vastai show instances --raw`; enabling SLA still requires console or REST — see [Finding SLA offers](#finding-sla-offers).)
API integrators: field names and filters diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 26f4a59f..e9869fcf 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -73,7 +73,7 @@ Think of an SLA offer as two host ideas plus one client choice: When a client rents an on-demand instance on your SLA-listed offer with a chosen target: -- They pay **compute** (GPU, storage, bandwidth) plus a **small hourly SLA charge** included in `dph_total`. +- While a rental runs they pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA charge**. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA charge at the quoted allocation — **not** bandwidth. - Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. - **Strong reliability relative to the client's target** → you keep the SLA charge for that day. - **Shortfalls** → credits flow to the client from your earnings (bounded by that day's covered compute). @@ -441,9 +441,12 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi **CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** ```bash -# Example: 2026-08-01 02:00:00 UTC → epoch seconds -# Linux: date -u -d '2026-08-01 02:00:00' +%s -vastai schedule maint MACHINE_ID --sdate 1785549600 --duration 2 --maintenance_category software +# Planned window: 2026-08-01 02:00:00 UTC (≥24 hours ahead when you run this) +# Prefer computing the epoch so the comment and value stay in sync: +vastai schedule maint MACHINE_ID \ + --sdate "$(date -u -d '2026-08-01 02:00:00' +%s)" \ + --duration 2 \ + --maintenance_category software ``` REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate": "2026-08-01T02:00:00Z"` (optional `"maintenance_reason": "OS kernel upgrade"`) — see [Schedule Maintenance](/api-reference/machines/schedule-maint). diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 36bd93b5..2e29ac5b 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,9 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA parameters (`--sla_r_claim`, `--sla_sigma_x`) are **not yet available** in the published CLI. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation) and [List Machine](/api-reference/machines/list-machine). - -Volume and duration options (`-v`, `-z`, `-l`) are available in the CLI today. +SLA listing flags are **not yet** in the published CLI — use console **Set Pricing → SLA** or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work in the CLI today. ## Usage diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 8b0f2858..adbb25cb 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -45,9 +45,11 @@ The same `schedule maint` command is used for both **planned** and **emergency** If SLA is enabled and you need planned downtime during an active rental, schedule at least 24 hours in advance. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ```bash -# Replace MACHINE_ID; set --sdate to a future UTC epoch (≥24h ahead for planned credit review) -# Linux: date -u -d '2026-08-01 02:00:00' +%s -vastai schedule maint MACHINE_ID --sdate 1785549600 --duration 2 --maintenance_category software +# Replace MACHINE_ID; --sdate must be a future UTC epoch (≥24h ahead for planned credit review) +vastai schedule maint MACHINE_ID \ + --sdate "$(date -u -d '2026-08-01 02:00:00' +%s)" \ + --duration 2 \ + --maintenance_category software ``` ### Emergency or unplanned maintenance diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index e1143f00..961e996e 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,9 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA parameters (`sla_r_claim`, `sla_sigma_x`) are **not yet available** in the published Python SDK. Use **Set Pricing → SLA** in the host console, or `PUT /api/v0/machines/create_asks/` via REST — see [SLA Offers](/host/sla-offers#api-for-automation). - -Volume and duration listing parameters (`vol_size`, `vol_price`, `duration`, `price_min_bid`) require the CLI or REST API today — they are not in the SDK signature below. +SLA listing parameters are **not yet** in the published Python SDK — use console **Set Pricing → SLA** or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration listing params require CLI or REST today. ## Signature From 7cb26605384836caa95f2daed73ba948f54dd154 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:44:48 -0700 Subject: [PATCH 031/250] docs(sla): address doc-review consensus (cycle 5) Align create-instance 410/storage notes and correct SDK volume/duration tooling scope. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 4 ++++ guides/instances/choosing/sla-coverage.mdx | 6 +++--- snippets/host/sdk/list-machine.mdx | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index b002255a..8fe467d7 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -77,6 +77,10 @@ bool = True | False ## Examples + +**Search quotes SLA pricing only.** `vastai create instance` cannot pass `target_reliability` today — use the web console or REST to enable coverage; see [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). + + ```bash # reliable single RTX 3090, no conflicts with stopped instances vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=False' diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 516ea4a2..aff79d46 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -175,16 +175,16 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe | Target on a non-SLA offer | HTTP 400 `invalid_args` | Search with `has_sla=true`; confirm `expected_reliability` | | Target out of range / invalid | HTTP 400 `invalid_args` | Use `0 < target_reliability < 1`; stay at or below a realistic host claim | | Offer unavailable / stale | HTTP 404 `invalid_args` (check `msg` for `no_such_ask`) | Re-search and rent a current offer ID | -| Offer no longer exists | HTTP 410 `no_such_ask` | Re-search for a new offer ID | +| Cannot start immediately (`cancel_unavail`) | HTTP 410 `no_such_ask` | Offer cannot start now; pick another offer or retry later — see [Create Instance](/api-reference/instances/create-instance) | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | -Hold storage constant when comparing `dph_total`: console Instance Disk Size defaults to **10 GB**, REST search `allocated_storage` defaults to **8 GB**, and CLI `--storage` defaults to **5 GiB**. Mismatched defaults make the same offer look differently priced across tools. +Hold storage constant when comparing `dph_total` and when chaining search → rent: console Instance Disk Size defaults to **10 GB**, REST search `allocated_storage` defaults to **8 GB**, and CLI `--storage` defaults to **5 GiB**. REST create-instance requires `disk` ≥ **8 GB**, so a CLI search at the 5 GiB default can quote a price you cannot rent via REST without raising storage — use ≥ 8 GB (or the same explicit value) for CLI search → REST rent flows. CLI `--storage` is in GiB; REST `allocated_storage` / create `disk` are in GB. ## What happens after you rent When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target, the host's claim, and confidence are fixed for that rental. +1. **Contract terms lock in** — your reliability target, the host's claim, and host confidence (how the host priced SLA around their claim) are fixed for that rental. You only compare the SLA charge or `dph_total` — confidence is a host-side pricing knob, not a setting you control. 2. **Daily billing** — you pay compute plus the SLA charge each day. 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — settlement credits improve your balance; strong days mean you paid the SLA charge with no credit. diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 961e996e..7797f163 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are **not yet** in the published Python SDK — use console **Set Pricing → SLA** or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration listing params require CLI or REST today. +SLA listing parameters are **not yet** in the published Python SDK — use console **Set Pricing → SLA** or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration listing options (`-v`, `-z`, `-l`) are available in the **CLI** today; they are not documented on the REST `list_machine` / `create_asks` body. ## Signature From bc649cf9716f28429f0284731a2927477e1974a2 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:50:53 -0700 Subject: [PATCH 032/250] docs(sla): address doc-review consensus (cycle 6) Correct search offer id labeling, console disk sizing path, and REST search parity filters. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/find-and-rent.mdx | 6 ++++-- guides/instances/choosing/sla-coverage.mdx | 4 ++++ host/sla-offers.mdx | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 8fe467d7..68c2b1de 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -146,7 +146,7 @@ vastai search offers 'cpu_arch=arm64' | `gpu_frac` | float | ratio of GPUs in the offer to GPUs in the system | | `gpu_display_active` | bool | True if the GPU has a display attached | | `has_avx` | bool | CPU supports AVX instruction set | -| `id` | int | instance unique ID | +| `id` | int | Offer/ask ID. Use this value when renting via create-instance (`PUT /api/v0/asks/{id}/`) | | `inet_down` | float | internet download speed in Mb/s | | `inet_down_cost` | float | internet download bandwidth cost in $/GB | | `inet_up` | float | internet upload speed in Mb/s | diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index e03e0f7c..652cd239 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -62,9 +62,11 @@ All stats shown are the portion of the total machine rented. ## Instance Disk Size -The storage slider is both a search filter and a parameter input which determines the storage allocation size - it's important to size this correctly before creating any instance. +The storage slider is both a search filter and a parameter input which determines the storage allocation size — size it correctly before you create an instance. -When the instance is created, the disk size is set and cannot be modified. It is important to estimate how much disk you will need and then to move the slider to the desired disk size. The default disk size for an instance is 10GB. Use the slider to allocate more or less, taking into consideration that providers charge for disk allocation even when the instance is stopped. When comparing `dph_total` across the console, CLI, and REST search, hold storage constant — defaults differ (console 10 GB, REST search 8 GB, CLI `--storage` 5 GiB); see [SLA Coverage](/guides/instances/choosing/sla-coverage#api-automation). +When the instance is created, the disk size is set and cannot be modified. Estimate how much disk you need, then move the slider to that size. The default disk size in the console is 10GB. Hosts charge for disk allocation even when the instance is stopped. + +If you compare prices across the console, CLI, and REST, match disk size first — defaults differ by channel. See [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation). ![Diskspace](/images/find-and-rent-diskspace.webp) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index aff79d46..e49edbfd 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -134,6 +134,8 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d ### API automation +Console-only renters can skip this section — use [In the web console](#in-the-web-console) above. + **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable): ```bash @@ -143,6 +145,8 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ -d '{ "limit": 20, "type": "ondemand", + "verified": {"eq": true}, + "rentable": {"eq": true}, "allocated_storage": 50, "order": [["dph_total", "asc"]], "target_reliability": {"eq": 0.95}, diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e9869fcf..e0fc952c 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -147,7 +147,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r **Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). -Higher confidence (tighter spread) → lower client SLA charges, but less room for reliability to slip before settlement credits grow. +**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA charges and less settlement exposure for the host. **Wider confidence** (console label **Wide**) → higher client SLA charges and more exposure on bad days. ### Validation rules From 72ae6d8cc630c33a30d9e663cc39b72399f717ad Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 08:55:33 -0700 Subject: [PATCH 033/250] docs(sla): address doc-review consensus (cycle 7) Align outage billing wording, confidence vs credit risk, and search target_reliability bounds. Co-authored-by: Cursor --- api-reference/openapi.yaml | 12 ++++++------ api-reference/openapi/yaml/search_offers.yaml | 6 ++++-- guides/instances/choosing/sla-coverage.mdx | 7 ++++--- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 4 ++-- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index f97b8ccf..99a35c35 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6660,12 +6660,12 @@ paths: host SLA claim. Example: {"gte": 0.99}' target_reliability: type: object - description: 'Client SLA coverage target (0-1). When set, search - prices include the SLA charge in dph_total - - and returns search.slaPremiumPerHour. Example: {"eq": 0.95} - - ' + description: "Client SLA coverage target. Value must be greater\ + \ than 0 and less than 1 (exclusive bounds \u2014\nsame as create-instance).\ + \ When set, search prices include the SLA charge in dph_total\ + \ and\nreturns search.slaPremiumPerHour. Pass the same target\ + \ again on PUT /api/v0/asks/{id}/ to\nenable coverage. Example:\ + \ {\"eq\": 0.95}\n" has_sla: type: object description: 'Restrict to offers with SLA enabled (true) or without diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index b93c497b..ea2b6f91 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -92,8 +92,10 @@ paths: target_reliability: type: object description: | - Client SLA coverage target (0-1). When set, search prices include the SLA charge in dph_total - and returns search.slaPremiumPerHour. Example: {"eq": 0.95} + Client SLA coverage target. Value must be greater than 0 and less than 1 (exclusive bounds — + same as create-instance). When set, search prices include the SLA charge in dph_total and + returns search.slaPremiumPerHour. Pass the same target again on PUT /api/v0/asks/{id}/ to + enable coverage. Example: {"eq": 0.95} has_sla: type: object description: | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index e49edbfd..89ea609f 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -21,15 +21,16 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing | Goal | Start here | | --- | --- | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | +| I use only the CLI today | Search can **quote** SLA pricing; enable coverage via console or [API automation](#api-automation) (REST) — `vastai create instance` cannot pass `target_reliability` yet | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | -| Automate search → rent → verify | [API automation](#api-automation) (REST; CLI cannot rent with SLA yet) | +| Automate search → rent → verify | [API automation](#api-automation) (REST) | SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). -You do not post escrow or collateral for SLA. You pay the SLA charge while the instance runs. Settlement happens automatically on a daily cadence. +You do not post escrow or collateral for SLA. You pay the SLA charge while your rental contract is active (including during outages, before settlement credits are applied). Settlement happens automatically on a daily UTC cadence. ## What SLA protects @@ -81,7 +82,7 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). 2. In Search filters (left filter bar), set **Reliability target** to your desired coverage level — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. -3. Optionally narrow to host SLA listings with an SLA-enabled / `has_sla` filter if shown. That filter only restricts which offers appear — it does **not** replace setting **Reliability target**. If you do not see a separate SLA toggle, set Reliability target and confirm the SLA charge line before rent. +3. Optionally narrow to host SLA listings with an SLA-enabled / `has_sla` filter if shown. **Filtering to SLA-enabled offers is not the same as enabling coverage** — you must still set **Reliability target** and confirm the SLA charge line before you rent. If you do not see a separate SLA toggle, set Reliability target and confirm the SLA charge line before rent. 4. Before you click **RENT**, confirm the price breakdown shows an **SLA charge** line. No SLA charge means no SLA coverage for that rental. 5. Rent as usual. Your target is locked at rent time. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 3d495b85..ae094624 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -258,7 +258,7 @@ The backtester accepts **`p`** (confidence) instead of `sla_sigma_x`. The mappin | `0.6667` | Normal (default) | `sla_sigma_x ≈ 0.5` | | `0.50` | Wide | `sla_sigma_x ≈ 1.0` | -Higher confidence (higher `p`) → tighter spread → lower SLA charges for clients at a given target, but less room for reliability to slip before credits grow. +Higher confidence (higher `p`) → tighter spread → lower simulated SLA charges for clients at a given target (more competitive `dph_total`). Tighter `p` does **not** reduce credit owed on a miss — use `worst_day_loss` and `reliability=` overrides to model settlement exposure. ## Error responses diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e0fc952c..4fc75b52 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -73,7 +73,7 @@ Think of an SLA offer as two host ideas plus one client choice: When a client rents an on-demand instance on your SLA-listed offer with a chosen target: -- While a rental runs they pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA charge**. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA charge at the quoted allocation — **not** bandwidth. +- While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA charge** — including during downtime. Settlement credits for missed targets are calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA charge at the quoted allocation — **not** bandwidth. - Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. - **Strong reliability relative to the client's target** → you keep the SLA charge for that day. - **Shortfalls** → credits flow to the client from your earnings (bounded by that day's covered compute). @@ -147,7 +147,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r **Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). -**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA charges and less settlement exposure for the host. **Wider confidence** (console label **Wide**) → higher client SLA charges and more exposure on bad days. +**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA charges (more competitive `dph_total`). **Wider confidence** (console label **Wide**) → higher client SLA charges. Confidence does **not** change the credit formula when a target is missed — use `worst_day_loss` and stress-test with the backtester `reliability=` override for tail-risk planning. ### Validation rules From 19245e76689936045d1ca3c30f9613ad9372d54f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 09:01:37 -0700 Subject: [PATCH 034/250] docs(sla): address doc-review consensus (cycle 8) Harden fleet listing example, add cancel/reschedule maintenance, and clarify daemon preflight. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-offers.mdx | 42 +++++++++++++++++----- snippets/host/cli/schedule-maint.mdx | 2 ++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 89ea609f..378869ad 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -82,7 +82,7 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). 2. In Search filters (left filter bar), set **Reliability target** to your desired coverage level — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. -3. Optionally narrow to host SLA listings with an SLA-enabled / `has_sla` filter if shown. **Filtering to SLA-enabled offers is not the same as enabling coverage** — you must still set **Reliability target** and confirm the SLA charge line before you rent. If you do not see a separate SLA toggle, set Reliability target and confirm the SLA charge line before rent. +3. Optionally narrow results with an SLA-enabled / `has_sla` filter if shown. Filtering listings is **not** the same as enabling coverage. 4. Before you click **RENT**, confirm the price breakdown shows an **SLA charge** line. No SLA charge means no SLA coverage for that rental. 5. Rent as usual. Your target is locked at rent time. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 4fc75b52..92ef32c3 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -271,22 +271,45 @@ Then `PUT /api/v0/machines/create_asks/` with merged fields. ### Fleet listing workflow (advanced — fleet operators only) -Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding claim/confidence. Skip unlisted machines. +`PUT /api/v0/machines/create_asks/` publishes a live listing (same as **LIST**). Only run this loop on machines you intend to list or update. Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding claim/confidence. Skip incomplete machines. + +**Before fleet SLA rollout:** + +1. Update host daemons fleet-wide per the [host setup guide](https://cloud.vast.ai/host/setup/). +2. On **Host → Machines**, confirm each machine is healthy (no red error status) and retry **LIST** / `create_asks` after the daemon reconnects. +3. If listing still returns `sla_daemon_outdated` after an update, contact support with the machine ID — there is no documented `show machines` daemon-version field for a preflight `jq` filter today. For multiple machines, loop sequentially — do not parallelize without backoff: -1. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields and required base pricing. -2. On `429`, sleep and retry with exponential backoff. -3. On `invalid_sla_params`, `sla_not_approved`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. +1. Skip machines missing base pricing fields. +2. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields (preserve existing claim/confidence when set). +3. On `429`, sleep and retry with exponential backoff. +4. On `invalid_sla_params`, `sla_not_approved`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. ```bash export VAST_API_KEY="YOUR_API_KEY" +# Set DRY_RUN=0 to apply; default prints payloads only +DRY_RUN="${DRY_RUN:-1}" machines=$(vastai show machines --raw) for id in $(vastai show machines -q); do - body=$(echo "$machines" | jq -c --arg id "$id" \ - '.machines[] | select((.id|tostring) == $id) | {machine: (.id|tonumber), price_gpu, end_date, min_chunk, sla_r_claim: 0.99, sla_sigma_x: 0.5}') + machine=$(echo "$machines" | jq -c --arg id "$id" \ + '.machines[] | select((.id|tostring) == $id)') + price=$(echo "$machine" | jq -r '.price_gpu // empty') + end=$(echo "$machine" | jq -r '.end_date // empty') + chunk=$(echo "$machine" | jq -r '.min_chunk // empty') + if [ -z "$price" ] || [ -z "$end" ] || [ -z "$chunk" ]; then + echo "skip $id: missing price_gpu/end_date/min_chunk"; continue + fi + # Preserve per-machine SLA tuning; defaults apply only when unset + body=$(echo "$machine" | jq -c \ + '{machine: (.id|tonumber), price_gpu, end_date, min_chunk, + sla_r_claim: (.sla_r_claim // 0.99), + sla_sigma_x: (.sla_sigma_x // 0.5)}') + if [ "$DRY_RUN" != "0" ]; then + echo "dry-run machine_id=$id payload: $body"; continue + fi resp=$(curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer $VAST_API_KEY" \ -H "Content-Type: application/json" \ @@ -296,7 +319,7 @@ for id in $(vastai show machines -q); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Tune claim/confidence per machine (backtester + earnings) before setting `DRY_RUN=0`. **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: @@ -451,6 +474,8 @@ vastai schedule maint MACHINE_ID \ REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate": "2026-08-01T02:00:00Z"` (optional `"maintenance_reason": "OS kernel upgrade"`) — see [Schedule Maintenance](/api-reference/machines/schedule-maint). +**Cancel or reschedule:** To cancel a window, use [`vastai cancel maint`](/host/cli/cancel-maint) (requires `machine_write`) or the [REST cancel-maintenance API](/api-reference/machines/cancel-maint). To reschedule, cancel the existing window, then run `schedule maint` with a new `--sdate` (still ≥24 hours ahead for planned SLA maintenance). + **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice credits do not apply to unplanned outages. See [CLI install](/cli/hello-world) if you have not set up the CLI. @@ -466,7 +491,8 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m ## When things go wrong - **Listing rejected (`invalid_sla_params`)** — Re-check claim and `sla_sigma_x` against [validation rules](#validation-rules). -- **`sla_not_approved` / `sla_daemon_outdated`** — Contact support or update the daemon from the host setup page. +- **`sla_not_approved`** — Contact support; you can keep a non-SLA listing while approval is pending. +- **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — Review reliability; re-run the backtester with a low `reliability` stress value (for example `0.01`). - **Severe outage** — Disable SLA on new contracts: open **Host → Machines** → **Set Pricing → SLA**, set claim to `0` (or use API `sla_r_claim=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index adbb25cb..31b66a36 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -60,6 +60,8 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned SLA credit review). + ## Examples ```bash From df333b30c5fbad533a4ebe55d2d6d9ccd09addb0 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 09:18:20 -0700 Subject: [PATCH 035/250] docs(sla): address doc-review consensus (cycle 9) Stop fleet script from inventing SLA claims; document maint rate limits; trim duplicate tooling warnings. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 6 +----- host/sla-offers.mdx | 20 +++++++++++++------- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 2 +- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 68c2b1de..fa3d277f 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -96,7 +96,7 @@ vastai search offers 'compute_cap > 610 total_flops > 5 datacenter=True' vastai search offers 'reliability>0.99 num_gpus=4 geolocation in [TW,SE]' # reliable RTX 3090 or 4090 NOT in China or Vietnam -vastai search offers 'reliability>0.99 gpu_name in ["RTX 4090", "RTX 3090"] geolocation notin [CN,VN]' +vastai search offers 'reliability>0.99 gpu_name in [RTX_4090, RTX_3090] geolocation notin [CN,VN]' # nvidia driver 535.86.05 or greater with various constraints vastai search offers 'disk_space>146 duration>24 gpu_ram>10 cuda_vers>=12.1 direct_port_count>=2 driver_version >= 535.86.05' @@ -108,10 +108,6 @@ vastai search offers 'reliability > 0.99 num_gpus>=4 verified=False rented=any' vastai search offers 'cpu_arch=arm64' ``` - -**Next step:** Search quotes SLA pricing only — see [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers) to rent with coverage (console or REST). - - ## Available Fields | Field | Type | Description | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 92ef32c3..0c5686ee 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -209,7 +209,7 @@ In the host console, open **Host Machines** → select your machine → **Set Pr New hosts: use the web console steps above first. Use the API when you need scripting, partial updates, or fleet automation. -SLA listing via `vastai list machine` and `VastAI.list_machine()` is **not yet available** in the published CLI/SDK. Use the REST API below until tooling support is released. +SLA listing via CLI/SDK is not available yet — use the REST API below (or console **Set Pricing → SLA**). See also [List Machine](/api-reference/machines/list-machine) for the same `create_asks` body. #### Before you start @@ -241,7 +241,11 @@ Replace `end_date` with a **future** Unix timestamp — past dates expire the of Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric payout risk. See [Offer End Date](/host/hosting-overview#offer-end-date). -Minimal example: + +Do not use the JSON below alone for a **first** listing. First-time `create_asks` requests must also include `min_chunk` and typical disk/bandwidth pricing — see [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). Use this as an **SLA-fields** reference when base pricing is already configured. + + +SLA fields example (existing listing): ```json { @@ -302,11 +306,13 @@ for id in $(vastai show machines -q); do if [ -z "$price" ] || [ -z "$end" ] || [ -z "$chunk" ]; then echo "skip $id: missing price_gpu/end_date/min_chunk"; continue fi - # Preserve per-machine SLA tuning; defaults apply only when unset + # Opt-in only: skip machines with no positive SLA claim (do not invent 0.99) + if ! echo "$machine" | jq -e '(.sla_r_claim // 0) > 0' >/dev/null; then + echo "skip $id: no positive sla_r_claim (enable SLA per machine first)"; continue + fi body=$(echo "$machine" | jq -c \ '{machine: (.id|tonumber), price_gpu, end_date, min_chunk, - sla_r_claim: (.sla_r_claim // 0.99), - sla_sigma_x: (.sla_sigma_x // 0.5)}') + sla_r_claim, sla_sigma_x: (.sla_sigma_x // 0.5)}') if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi @@ -319,7 +325,7 @@ for id in $(vastai show machines -q); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Tune claim/confidence per machine (backtester + earnings) before setting `DRY_RUN=0`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure claim/confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: @@ -461,7 +467,7 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi **Planned SLA maintenance (may earn credit):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for SLA credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. Credit eligibility is evaluated on a case-by-case basis. -**CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** +**CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** Schedule maintenance **sequentially** across a fleet — the API is rate-limited (~2.5 requests/second). On HTTP 429, wait and retry with backoff (for example, `sleep 2` between machines). ```bash # Planned window: 2026-08-01 02:00:00 UTC (≥24 hours ahead when you run this) diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 2e29ac5b..342620c6 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are **not yet** in the published CLI — use console **Set Pricing → SLA** or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work in the CLI today. +SLA listing flags are not in the published CLI yet — see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. ## Usage diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 31b66a36..432a4d2a 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -60,7 +60,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned SLA credit review). +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned SLA credit review). Across many machines, schedule sequentially and back off on HTTP 429 (~2.5 req/s). ## Examples diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 7797f163..341376ae 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are **not yet** in the published Python SDK — use console **Set Pricing → SLA** or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration listing options (`-v`, `-z`, `-l`) are available in the **CLI** today; they are not documented on the REST `list_machine` / `create_asks` body. +SLA listing parameters are not in the published Python SDK yet — see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration listing options are CLI-only today. ## Signature From 894107ae7359f1b37a46d9df56f061ac274c6ecc Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 09:24:34 -0700 Subject: [PATCH 036/250] docs(sla): address doc-review consensus (cycle 10) Clarify cross-channel storage defaults and mark create-instance SLA as REST-only in OpenAPI. Co-authored-by: Cursor --- api-reference/openapi.yaml | 38 ++++++++----------- .../openapi/yaml/create_instance.yaml | 4 +- guides/instances/choosing/sla-coverage.mdx | 10 ++++- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 99a35c35..3af10b99 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1579,29 +1579,21 @@ paths: /api/v0/asks/{id}: put: summary: create instance - description: 'Creates a new instance by accepting an "ask" contract from a provider. - - - - Use the search offers endpoint to discover available machines. - - - If `template_id` is provided, those template defaults are either merged - or overridden by parameters specified in the request body. - - - **Template Precedence Rules:** - - - **Scalar fields** (image, disk, runtype, etc.): Request value overrides - template value - - - **`env`**: Merged by key. Request values win on key conflicts - - - **`extra_filters`**: Merged by key. Request values win on key conflicts - - - For detailed template usage, see [Creating and Using Templates with API](/api-reference/creating-and-using-templates-with-api). - - - CLI Usage: `vastai create instance [options]`' + description: "Creates a new instance by accepting an \"ask\" contract from a\ + \ provider.\n\n- Use the search offers endpoint to discover available machines.\n\ + - If `template_id` is provided, those template defaults are either merged\ + \ or overridden by parameters specified in the request body.\n\n**Template\ + \ Precedence Rules:**\n- **Scalar fields** (image, disk, runtype, etc.): Request\ + \ value overrides template value\n- **`env`**: Merged by key. Request values\ + \ win on key conflicts\n- **`extra_filters`**: Merged by key. Request values\ + \ win on key conflicts\n\nFor detailed template usage, see [Creating and Using\ + \ Templates with API](/api-reference/creating-and-using-templates-with-api).\n\ + \n**SLA note:** `target_reliability` is REST-only at rent time. The published\ + \ CLI and SDK cannot pass this field until support ships. Use the web console\ + \ or `PUT /api/v0/asks/{id}/` with `target_reliability` in the request body\ + \ to enable SLA coverage \u2014 see [SLA Coverage](/guides/instances/choosing/sla-coverage).\n\ + \nCLI Usage: `vastai create instance [options]` (no `target_reliability`\ + \ flag today)" security: - BearerAuth: [] tags: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 0324cf0d..d5627f18 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -23,7 +23,9 @@ paths: For detailed template usage, see [Creating and Using Templates with API](/api-reference/creating-and-using-templates-with-api). - CLI Usage: `vastai create instance [options]` + **SLA note:** `target_reliability` is REST-only at rent time. The published CLI and SDK cannot pass this field until support ships. Use the web console or `PUT /api/v0/asks/{id}/` with `target_reliability` in the request body to enable SLA coverage — see [SLA Coverage](/guides/instances/choosing/sla-coverage). + + CLI Usage: `vastai create instance [options]` (no `target_reliability` flag today) security: - BearerAuth: [] tags: diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 378869ad..ab2c4c5a 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -21,7 +21,7 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing | Goal | Start here | | --- | --- | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | -| I use only the CLI today | Search can **quote** SLA pricing; enable coverage via console or [API automation](#api-automation) (REST) — `vastai create instance` cannot pass `target_reliability` yet | +| I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances --raw` (`target_reliability` > 0). To enable coverage, use the console or [API automation](#api-automation) (REST) | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | | Automate search → rent → verify | [API automation](#api-automation) (REST) | @@ -183,7 +183,13 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe | Cannot start immediately (`cancel_unavail`) | HTTP 410 `no_such_ask` | Offer cannot start now; pick another offer or retry later — see [Create Instance](/api-reference/instances/create-instance) | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | -Hold storage constant when comparing `dph_total` and when chaining search → rent: console Instance Disk Size defaults to **10 GB**, REST search `allocated_storage` defaults to **8 GB**, and CLI `--storage` defaults to **5 GiB**. REST create-instance requires `disk` ≥ **8 GB**, so a CLI search at the 5 GiB default can quote a price you cannot rent via REST without raising storage — use ≥ 8 GB (or the same explicit value) for CLI search → REST rent flows. CLI `--storage` is in GiB; REST `allocated_storage` / create `disk` are in GB. +| Channel | Default storage | Field | Units | +| --- | --- | --- | --- | +| Console | 10 GB | Instance disk size (UI) | GB | +| REST search (`POST /api/v0/bundles/`) | 8 GB | `allocated_storage` | GB | +| CLI (`vastai search offers`) | 5 GiB | `--storage` | GiB | + +**Rule:** Set the same explicit storage in search and create-instance. REST create-instance `disk` must be ≥ **8 GB** when you pass it (omit uses platform defaults — do not assume the CLI search default of 5 is rentable via REST). Pass matching numeric values across channels when chaining CLI search → REST rent (CLI help labels GiB; REST fields are labeled GB). ## What happens after you rent From 67c503be27399b3787b70f87805941835ad8df76 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 09:29:25 -0700 Subject: [PATCH 037/250] docs(sla): address doc-review consensus (cycle 11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clarify GiB/GB search→rent integers, console-only SLA credits, and create-instance SLA gaps. Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 4 ++++ guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 12 +++++++++--- sdk/python/reference/create-instance.mdx | 4 ++++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index faf04d2b..00b3bea5 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -5,6 +5,10 @@ sidebarTitle: "create instance" Create a new instance + +**SLA coverage:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable SLA. See [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). + + ## Usage ```bash diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 652cd239..9dde3170 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -58,7 +58,7 @@ All stats shown are the portion of the total machine rented. - Max Duration: The maximum length of a rental contract on this machine - Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host SLA claim. - Rental Option: RENT button -- **SLA (optional):** Available on **on-demand** rentals only. Set a **reliability target** in Search, then confirm the price breakdown includes an **SLA charge** line before clicking **RENT** — see [SLA Coverage](/guides/instances/choosing/sla-coverage). +- **SLA (optional):** Available on **on-demand** rentals only. Set a **reliability target** in Search, then confirm the price breakdown includes an **SLA charge** line before clicking **RENT**. Host SLA claim (`expected_reliability`) does not protect you unless you opt in — see [SLA Coverage](/guides/instances/choosing/sla-coverage). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index ab2c4c5a..b0ac6330 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -76,6 +76,10 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 ## Finding SLA offers + +**No SLA charge line in the price breakdown = no SLA coverage.** Filtering to SLA listings or searching with a reliability target only quotes pricing. Coverage requires setting **Reliability target** in the console (or passing `target_reliability` on REST create-instance) before you rent. + + **Decision rule:** Search filters **quote** SLA pricing only. Coverage activates only when you rent via the **web console** (Reliability target set) or **REST** create-instance (`target_reliability` on `PUT /api/v0/asks/{id}/`). The CLI cannot enable SLA at rent time today — see [API automation](#api-automation) for the minimum REST rent path. ### In the web console @@ -183,13 +187,13 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe | Cannot start immediately (`cancel_unavail`) | HTTP 410 `no_such_ask` | Offer cannot start now; pick another offer or retry later — see [Create Instance](/api-reference/instances/create-instance) | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | -| Channel | Default storage | Field | Units | +| Channel | Default storage | Field | Units (label) | | --- | --- | --- | --- | | Console | 10 GB | Instance disk size (UI) | GB | | REST search (`POST /api/v0/bundles/`) | 8 GB | `allocated_storage` | GB | | CLI (`vastai search offers`) | 5 GiB | `--storage` | GiB | -**Rule:** Set the same explicit storage in search and create-instance. REST create-instance `disk` must be ≥ **8 GB** when you pass it (omit uses platform defaults — do not assume the CLI search default of 5 is rentable via REST). Pass matching numeric values across channels when chaining CLI search → REST rent (CLI help labels GiB; REST fields are labeled GB). +**Match disk size when comparing prices.** Defaults differ by channel. When chaining CLI search → REST rent, use the **same integer** on both sides (for example `--storage 50` then `"disk": 50`) — the platform treats that number identically even though REST fields are labeled GB and CLI help says GiB. REST create-instance `disk` must be ≥ **8** when you pass it; do not assume the CLI default of 5 is rentable via REST. ## What happens after you rent @@ -302,7 +306,9 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -Check **Account → Billing** and instance charges. SLA line items appear alongside compute charges for each settled day. +**Console:** After UTC settlement, open **Account → Billing** and look for SLA credit line items alongside compute charges. + +**API:** SLA settlement credits are **not** exposed in `GET /api/v0/charges/` today (documented charge `type` values: `gpu`, `disk`, `bwd`, `bwu`). Use the console for reconciliation until a client billing endpoint documents SLA settlement rows. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/machines/show-earnings) (`sla_earn`) — that path is for hosts, not renters. ## Related documentation diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index cad79260..6b09f7ed 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -5,6 +5,10 @@ sidebarTitle: "create_instance" Create a new instance from a contract offer ID. + +**SLA coverage:** `target_reliability` is not available on `create_instance()` today. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable SLA — see [SLA Coverage](/guides/instances/choosing/sla-coverage#api-automation). + + ## Signature ```python From 631e28e2b351a4cd07544da5374d85aece25d9ec Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 09:34:17 -0700 Subject: [PATCH 038/250] docs(sla): address doc-review consensus (cycle 12) Fix backtester confidence wording, create-instance offer-id labeling, and OpenAPI disk/lookback notes. Co-authored-by: Cursor --- api-reference/openapi.yaml | 10 ++++++++-- api-reference/openapi/yaml/create_instance.yaml | 3 ++- api-reference/openapi/yaml/sla_backtest.yaml | 3 ++- cli/reference/create-instance.mdx | 6 +++--- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 4 ++-- snippets/host/cli/schedule-maint.mdx | 2 +- 7 files changed, 19 insertions(+), 11 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 3af10b99..dbca1c9c 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1638,7 +1638,9 @@ paths: disk: type: number format: float - description: 'Size of local disk partition (in GB) + minimum: 8 + description: 'Size of local disk partition (in GB). Minimum 8 when + specified. ' target_reliability: @@ -9258,7 +9260,11 @@ paths: description: 'Replays a machine''s historical compute earnings and uptime through SLA settlement math - to preview SLA charges and credits before listing with SLA. + to preview SLA charges and credits before listing with SLA. The maximum date + range is + + 366 days (inclusive); the default lookback is 90 days when custom dates are + omitted. Requires `machine_read` permission. See [SLA Earnings Backtester](/host/sla-backtester) diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index d5627f18..7d0bdb59 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -63,8 +63,9 @@ paths: disk: type: number format: float + minimum: 8 description: | - Size of local disk partition (in GB) + Size of local disk partition (in GB). Minimum 8 when specified. target_reliability: type: number format: float diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index 162264cd..542434a6 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -13,7 +13,8 @@ paths: operationId: slaBacktest description: | Replays a machine's historical compute earnings and uptime through SLA settlement math - to preview SLA charges and credits before listing with SLA. + to preview SLA charges and credits before listing with SLA. The maximum date range is + 366 days (inclusive); the default lookback is 90 days when custom dates are omitted. Requires `machine_read` permission. See [SLA Earnings Backtester](/host/sla-backtester) for usage guide. security: diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 00b3bea5..fbfceb98 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -5,9 +5,9 @@ sidebarTitle: "create instance" Create a new instance - + **SLA coverage:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable SLA. See [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). - + ## Usage @@ -18,7 +18,7 @@ vastai create instance ID [OPTIONS] [--args ...] ## Arguments - id of instance type to launch (returned from search offers) + Offer/ask ID from search offers (the value passed to create-instance / `PUT /api/v0/asks/{id}/`). This is not a running instance ID. ## Options diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index ae094624..eac84b9c 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -258,7 +258,7 @@ The backtester accepts **`p`** (confidence) instead of `sla_sigma_x`. The mappin | `0.6667` | Normal (default) | `sla_sigma_x ≈ 0.5` | | `0.50` | Wide | `sla_sigma_x ≈ 1.0` | -Higher confidence (higher `p`) → tighter spread → lower simulated SLA charges for clients at a given target (more competitive `dph_total`). Tighter `p` does **not** reduce credit owed on a miss — use `worst_day_loss` and `reliability=` overrides to model settlement exposure. +Tighter confidence (higher `p`) does **not** reduce credit owed on a miss — use `worst_day_loss` and `reliability=` overrides to model settlement exposure. ## Error responses diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 0c5686ee..1d4bddc0 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -48,7 +48,7 @@ On outage days you may still bill clients for **intended** compute **and** owe S -**Rental types:** SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible instances on an SLA-enabled machine are not SLA-covered; on-demand contracts on the same machine are. If a client attempts to reserve or prepay an SLA-enabled offer, the request is rejected. +**Rental types:** SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible instances on an SLA-enabled machine are not SLA-covered; on-demand contracts on the same machine are. Reserved or prepay attempts on an SLA-enabled offer are not supported — use on-demand to rent with SLA. - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. @@ -467,7 +467,7 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi **Planned SLA maintenance (may earn credit):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for SLA credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. Credit eligibility is evaluated on a case-by-case basis. -**CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** Schedule maintenance **sequentially** across a fleet — the API is rate-limited (~2.5 requests/second). On HTTP 429, wait and retry with backoff (for example, `sleep 2` between machines). +**CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** Schedule maintenance **sequentially** across a fleet. On HTTP 429, wait and retry with backoff (for example, `sleep 2` between machines). See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash # Planned window: 2026-08-01 02:00:00 UTC (≥24 hours ahead when you run this) diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 432a4d2a..0438a47b 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -60,7 +60,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned SLA credit review). Across many machines, schedule sequentially and back off on HTTP 429 (~2.5 req/s). +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned SLA credit review). Across many machines, schedule sequentially and back off on HTTP 429. ## Examples From 8f8efd061c94058b71bacb9ec6f61685fcc0b333 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 09:39:29 -0700 Subject: [PATCH 039/250] docs(sla): address doc-review consensus (cycle 13) Surface client billing reconciliation limits early and align create-instance CLI examples with shipped vastai. Co-authored-by: Cursor --- api-reference/openapi.yaml | 4 ++-- api-reference/openapi/yaml/create_instance.yaml | 2 +- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 12 +++++++----- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index dbca1c9c..9c3f490a 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1592,8 +1592,8 @@ paths: \ CLI and SDK cannot pass this field until support ships. Use the web console\ \ or `PUT /api/v0/asks/{id}/` with `target_reliability` in the request body\ \ to enable SLA coverage \u2014 see [SLA Coverage](/guides/instances/choosing/sla-coverage).\n\ - \nCLI Usage: `vastai create instance [options]` (no `target_reliability`\ - \ flag today)" + \nCLI Usage: `vastai create instance --image [options]`\ + \ (no `target_reliability` flag today)" security: - BearerAuth: [] tags: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 7d0bdb59..191ed058 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -25,7 +25,7 @@ paths: **SLA note:** `target_reliability` is REST-only at rent time. The published CLI and SDK cannot pass this field until support ships. Use the web console or `PUT /api/v0/asks/{id}/` with `target_reliability` in the request body to enable SLA coverage — see [SLA Coverage](/guides/instances/choosing/sla-coverage). - CLI Usage: `vastai create instance [options]` (no `target_reliability` flag today) + CLI Usage: `vastai create instance --image [options]` (no `target_reliability` flag today) security: - BearerAuth: [] tags: diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 9dde3170..b28d2236 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -58,7 +58,7 @@ All stats shown are the portion of the total machine rented. - Max Duration: The maximum length of a rental contract on this machine - Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host SLA claim. - Rental Option: RENT button -- **SLA (optional):** Available on **on-demand** rentals only. Set a **reliability target** in Search, then confirm the price breakdown includes an **SLA charge** line before clicking **RENT**. Host SLA claim (`expected_reliability`) does not protect you unless you opt in — see [SLA Coverage](/guides/instances/choosing/sla-coverage). +- **SLA (optional):** On-demand offers may include an optional SLA upsell. The host’s advertised SLA claim (not the Reliability Score above) sets the ceiling for your target. Confirm an **SLA charge** line before **RENT** — see [SLA Coverage](/guides/instances/choosing/sla-coverage). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b0ac6330..5ba51dd1 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -23,7 +23,7 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | | I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances --raw` (`target_reliability` > 0). To enable coverage, use the console or [API automation](#api-automation) (REST) | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | -| Automate search → rent → verify | [API automation](#api-automation) (REST) | +| Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** SLA settlement credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). @@ -61,7 +61,7 @@ Bandwidth is billed separately from usage (`inet_*` rates) and is **not** includ | Host SLA claim | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher claim → lower SLA charge at a given target | | Host confidence | Host-side pricing setting that affects SLA charge size. **You do not set this** — the host chooses it, and it is **not shown on offer cards**. Compare offers using `dph_total` or the SLA charge line in the price breakdown | -**Rule of thumb:** pick a target **at or below** the host's claim for the best value. Asking for 99% coverage on a host who only claims 95% costs much more than asking for 95% on a host who claims 99%. +**Rule of thumb:** pick a target **at or below** the host's claim for the best value. Asking for 99% coverage on a host who only claims 95% costs much more than asking for 95% on a host who claims 99%. In search results, the host claim appears as **expected reliability** / SLA claim on the offer (API: `expected_reliability`) — not the Reliability Score on the card. ### Example: H100 at $3.50/hr GPU @@ -141,6 +141,8 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d Console-only renters can skip this section — use [In the web console](#in-the-web-console) above. +**Billing reconciliation:** SLA settlement credits appear in the console billing UI today. They are not included in `GET /api/v0/charges/` and client webhooks for SLA credits are not available — plan manual console reconciliation after UTC settlement (see [FAQ](#where-do-i-see-historical-sla-credits)). + **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable): ```bash @@ -278,9 +280,9 @@ To find SLA-covered instances, filter **client-side** from the show-instances re | --- | --- | | Your reliability target | `target_reliability` | | SLA charge rate | `search.slaPremiumPerHour` / `instance.slaPremiumPerHour` | -| Host SLA claim (offers / contracts) | `expected_reliability` / `sla_r_claim` | +| Host SLA claim (offers / contracts) | `expected_reliability` | -Host confidence is a host-side pricing setting and is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers. +Host ask field `sla_r_claim` is host-side only — see [SLA Offers](/host/sla-offers). Host confidence is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers.
## When SLA is not available @@ -308,7 +310,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta **Console:** After UTC settlement, open **Account → Billing** and look for SLA credit line items alongside compute charges. -**API:** SLA settlement credits are **not** exposed in `GET /api/v0/charges/` today (documented charge `type` values: `gpu`, `disk`, `bwd`, `bwu`). Use the console for reconciliation until a client billing endpoint documents SLA settlement rows. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/machines/show-earnings) (`sla_earn`) — that path is for hosts, not renters. +**API:** SLA settlement credits are **not** exposed in `GET /api/v0/charges/` today (documented charge `type` values: `gpu`, `disk`, `bwd`, `bwu`). Use the console for reconciliation until a client billing endpoint documents SLA settlement rows. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. ## Related documentation From 4ed8d259dd99ea7acaf1eef64c2a563068a9b861 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 09:47:22 -0700 Subject: [PATCH 040/250] docs(sla): use vastai in create-instance OpenAPI examples Co-authored-by: Cursor --- api-reference/openapi/yaml/create_instance.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 191ed058..7db5e9ee 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -343,6 +343,6 @@ x-cli-commands: endpoint: /api/v0/asks/{id}/ method: PUT examples: - - vast create instance 1234567 --image tensorflow/tensorflow:latest-gpu --disk 32 - - vast create instance 1234567 --template abc123def456 - - vast create instance 1234567 --price 0.4 --disk 100 --env JUPYTER_TOKEN=abc123 \ No newline at end of file + - vastai create instance 1234567 --image tensorflow/tensorflow:latest-gpu --disk 32 + - vastai create instance 1234567 --template abc123def456 + - vastai create instance 1234567 --price 0.4 --disk 100 --env JUPYTER_TOKEN=abc123 \ No newline at end of file From d66a97aa3d74f458e88cdd205a9c826930d26cd4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 09:48:09 -0700 Subject: [PATCH 041/250] docs(sla): address doc-review consensus (cycle 14) Clarify self-test billing, add host checklist and SLA key recipe, and fix offer-id / date platform notes. Co-authored-by: Cursor --- api-reference/permissions.mdx | 17 +++++++++++++++++ guides/instances/choosing/sla-coverage.mdx | 12 ++++++------ host/hosting-overview.mdx | 4 ++-- host/sla-offers.mdx | 10 ++++++++++ sdk/python/reference/create-instance.mdx | 2 +- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 2 ++ snippets/host/sdk/list-machine.mdx | 2 +- 8 files changed, 40 insertions(+), 11 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index cb08e0b6..a1355fdf 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -208,6 +208,23 @@ Below is the complete mapping of which endpoints each permission category contro - [Unlist Machine](/api-reference/machines/unlist-machine) - [Unlist Volume](/api-reference/volumes/unlist-volume) +**Host SLA scoped-key recipe (minimum):** + +```json +{ + "machine_read": {}, + "machine_write": {}, + "billing_read": {} +} +``` + +| Task | Permission | Console fallback | +| --- | --- | --- | +| List/update SLA via `create_asks` | `machine_write` | **Set Pricing → SLA** → LIST | +| SLA backtester | `machine_read` | Console SLA preview | +| Schedule / cancel maintenance | `machine_write` | None (CLI/REST only) | +| Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | + ### misc - [Show Workergroups](/api-reference/serverless/show-workergroup) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 5ba51dd1..332c0db5 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -276,13 +276,13 @@ Show-instances output may include `target_reliability` and price fields under `s To find SLA-covered instances, filter **client-side** from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Prefer client-side filtering in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone for SLA detection. -| Client-visible concept | API / raw field | -| --- | --- | -| Your reliability target | `target_reliability` | -| SLA charge rate | `search.slaPremiumPerHour` / `instance.slaPremiumPerHour` | -| Host SLA claim (offers / contracts) | `expected_reliability` | +| Client-visible concept | Search / bundles | Active rental (`GET /api/v1/instances/`) | +| --- | --- | --- | +| Your reliability target | `target_reliability` (quote only until rent) | `target_reliability` | +| SLA charge rate | `search.slaPremiumPerHour` | `instance.slaPremiumPerHour` | +| Host SLA claim | `expected_reliability` | `sla_r_claim` | -Host ask field `sla_r_claim` is host-side only — see [SLA Offers](/host/sla-offers). Host confidence is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers. +Host ask field `sla_r_claim` on listings is host-side; on active rentals the locked claim appears as `sla_r_claim` in show-instances. Host confidence is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers.
## When SLA is not available diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 31a8ce39..ed9df6e9 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -213,7 +213,7 @@ To rent your own machine you will need to first search the offers with your mach ./vastai show machines ``` -Then for each machine id you will need to find the available instance IDs. +Then for each machine id you will need to find the available **offer/ask IDs** (not running instance IDs). ```text Text ./vastai search offers 'machine_id=12345 verified=any' @@ -221,7 +221,7 @@ Then for each machine id you will need to find the available instance IDs. Replace 12345 with your actual machine ID in question. You can see the number of available listings as well as information about the machine. This is the fastest way to also see all the offers listed for a given machine. The website GUI stacks similar offers and so it is not easy to see all the listings for a given machine. That is not a problem for the CLI. -Take the ID number from the first column and use that to create a free instance on your own machine. This example loads the latest pytorch image along with both jupyter and ssh direct launch modes. +Take the **offer/ask ID** from the first column of search results and use it with `create instance`. This creates a **test rental billed to your separate client account** like any other rental (it is not free). Host earnings offset client spend only after rentals settle. This example loads the latest pytorch image along with both jupyter and ssh direct launch modes. ```text Text vastai create instance --image pytorch/pytorch:latest --jupyter --direct --env '-e TZ=PDT -p 22:22 -p 8080:8080' diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1d4bddc0..78c1e9aa 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -25,6 +25,16 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative | I list with CLI only (no SLA flags yet) | **Set Pricing → SLA** + **LIST** in the console, or REST `PUT /api/v0/machines/create_asks/` — SLA flags are **not** in `vastai list machine` yet | | Monitor settlement after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | +## SLA host checklist + +1. Complete [host setup](https://cloud.vast.ai/host/setup/) and list your machine. +2. Test on a [separate client account](/host/hosting-overview#testing-your-own-machine) (billed like any rental). +3. Install the [CLI](/cli/hello-world) (required for SLA maintenance scheduling). +4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). +5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set claim/confidence. +6. Enable SLA listing and verify in search (`machine_id=` filter). +7. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental. + ## Before you enable SLA diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 6b09f7ed..c03ab4f4 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -48,7 +48,7 @@ VastAI.create_instance( ## Parameters - id of instance type to launch (returned from search offers) + Offer/ask ID from search offers (same value as CLI create-instance). This is not a running instance ID. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 342620c6..863b1404 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. ## Usage diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 0438a47b..e4dbddc9 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -46,6 +46,8 @@ If SLA is enabled and you need planned downtime during an active rental, schedul ```bash # Replace MACHINE_ID; --sdate must be a future UTC epoch (≥24h ahead for planned credit review) +# Linux: date -u -d '2026-08-01 02:00:00' +%s +# macOS: date -u -j -f '%Y-%m-%d %H:%M:%S' '2026-08-01 02:00:00' +%s vastai schedule maint MACHINE_ID \ --sdate "$(date -u -d '2026-08-01 02:00:00' +%s)" \ --duration 2 \ diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 341376ae..583ab8e8 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration listing options are CLI-only today. +SLA listing parameters are not in the published Python SDK yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration listing options are CLI-only today. ## Signature From 292943188141bb44e8cc8f8262e09aef5764f2b5 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 10:05:47 -0700 Subject: [PATCH 042/250] docs(sla): address doc-review consensus (cycle 15) Wrap host SLA scoped-key JSON in required api object and fix create-instance example fences. Co-authored-by: Cursor --- api-reference/permissions.mdx | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index a1355fdf..a8ba08db 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -208,13 +208,15 @@ Below is the complete mapping of which endpoints each permission category contro - [Unlist Machine](/api-reference/machines/unlist-machine) - [Unlist Volume](/api-reference/volumes/unlist-volume) -**Host SLA scoped-key recipe (minimum):** +**Host SLA scoped-key recipe (minimum):** Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. ```json { - "machine_read": {}, - "machine_write": {}, - "billing_read": {} + "api": { + "machine_read": {}, + "machine_write": {}, + "billing_read": {} + } } ``` @@ -225,6 +227,20 @@ Below is the complete mapping of which endpoints each permission category contro | Schedule / cancel maintenance | `machine_write` | None (CLI/REST only) | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | +**Client SLA search → REST rent (minimum):** + +```json +{ + "api": { + "misc": {}, + "instance_write": {}, + "instance_read": {} + } +} +``` + +SLA settlement credits are console-only for renters today — `billing_read` does not expose client SLA credit rows in `GET /api/v0/charges/`. + ### misc - [Show Workergroups](/api-reference/serverless/show-workergroup) From f493356e25672d0291e8f58909a8334a03815a7b Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 10:12:14 -0700 Subject: [PATCH 043/250] docs(sla): fix create-instance example fences (cycle 15 follow-up) Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index fbfceb98..e71bbe2c 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -133,7 +133,7 @@ Performs the same action as pressing the "RENT" button on the website at https:/ Creates an instance from an offer ID (which is returned from "search offers"). Each offer ID can only be used to create one instance. Besides the offer ID, you must pass in an '`--image`' argument as a minimum. -If you use args/entrypoint launch mode, we create a container from your image as is, without attempting to inject ssh and or jupyter. +If you use args/entrypoint launch mode, we create a container from your image as is, without attempting to inject SSH or Jupyter. If you use the args launch mode, you can override the entrypoint with `--entrypoint`, and pass arguments to the entrypoint with `--args`. If you use `--args`, that must be the last argument, as any following tokens are consumed into the args string. For ssh/jupyter launch types, use `--onstart-cmd` to pass in startup script, instead of `--entrypoint` and `--args`. @@ -147,18 +147,20 @@ vastai create instance 384826 --template_hash 661d064bbda1f2a133816b6d55da07c3 - # create an on-demand instance with the pytorch/pytorch image, 40GB of disk, open 8081 udp, direct ssh, set hostname to billybob, and a small onstart script vastai create instance 6995713 --image pytorch/pytorch --disk 40 --env '-p 8081:8081/udp -h billybob' --ssh --direct --onstart-cmd "env | grep _ >> /etc/environment; echo 'starting up'"; -# create an on-demand instance with the bobsrepo/pytorch:latest image, 20GB of disk, open 22, 8080, jupyter ssh, and set some env variables -vastai create instance 384827 --image bobsrepo/pytorch:latest --login '-u bob -p 9d8df!fd89ufZ docker.io' --jupyter --direct --env '-e TZ=PDT -e XNAME=XX4 -p 22:22 -p 8080:8080' --disk 20 +# create an on-demand instance with a private image (use your registry password, not a real secret in docs) +vastai create instance 384827 --image YOUR_REGISTRY/pytorch:latest --login '-u YOUR_USER -p YOUR_PASSWORD docker.io' --jupyter --direct --env '-e TZ=PDT -e XNAME=XX4 -p 22:22 -p 8080:8080' --disk 20 # create an on-demand instance with the pytorch/pytorch image, 40GB of disk, override the entrypoint to bash and pass bash a simple command to keep the instance running. (args launch without ssh/jupyter) vastai create instance 5801802 --image pytorch/pytorch --disk 40 --onstart-cmd 'bash' --args -c 'echo hello; sleep infinity;' # create an interruptible (spot) instance with the PyTorch (cuDNN Devel) template, 64GB of disk, and a bid price of $0.10/hr vastai create instance 384826 --template_hash 661d064bbda1f2a133816b6d55da07c3 --disk 64 --bid_price 0.1 +``` + +Return value — JSON reporting the instance ID of the newly created instance: -Return value: -Returns a json reporting the instance ID of the newly created instance: -{'success': True, 'new_contract': 7835610} +```json +{"success": true, "new_contract": 7835610} ``` ## Global Options From 2abee14d7d14bca2832ba6dc0a0461f378e9d48b Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 27 Jul 2026 10:12:52 -0700 Subject: [PATCH 044/250] docs(sla): address doc-review consensus (cycle 16) Align instances pagination defaults, document SLA search CLI warnings, and relocate client key recipe. Co-authored-by: Cursor --- api-reference/openapi.yaml | 7 +++-- .../openapi/yaml/show_instances.yaml | 4 +-- api-reference/permissions.mdx | 28 +++++++++---------- cli/reference/search-offers.mdx | 5 ++++ guides/instances/choosing/sla-coverage.mdx | 4 +-- host/hosting-overview.mdx | 4 +-- 6 files changed, 29 insertions(+), 23 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 9c3f490a..c22d172f 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8068,11 +8068,12 @@ paths: - name: limit in: query required: false - description: "Instances per page. Default 25, max 25. Values \u2264 0 are\ - \ treated as 5." + description: "Instances per page. Maximum 25. Omit or set \u2264 0 to use\ + \ the server default (currently 5). Prefer an explicit `limit` (for example\ + \ 25)." schema: type: integer - default: 25 + default: 5 maximum: 25 example: 25 - name: after_token diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index 08f768fc..c2f0a921 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -21,10 +21,10 @@ paths: - name: limit in: query required: false - description: Instances per page. Default 25, max 25. Values ≤ 0 are treated as 5. + description: Instances per page. Maximum 25. Omit or set ≤ 0 to use the server default (currently 5). Prefer an explicit `limit` (for example 25). schema: type: integer - default: 25 + default: 5 maximum: 25 example: 25 - name: after_token diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index a8ba08db..24a21a7e 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -227,20 +227,6 @@ Below is the complete mapping of which endpoints each permission category contro | Schedule / cancel maintenance | `machine_write` | None (CLI/REST only) | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | -**Client SLA search → REST rent (minimum):** - -```json -{ - "api": { - "misc": {}, - "instance_write": {}, - "instance_read": {} - } -} -``` - -SLA settlement credits are console-only for renters today — `billing_read` does not expose client SLA credit rows in `GET /api/v0/charges/`. - ### misc - [Show Workergroups](/api-reference/serverless/show-workergroup) @@ -254,6 +240,20 @@ SLA settlement credits are console-only for renters today — `billing_read` doe - [Search Offers](/api-reference/search/search-offers) - [Search Volumes](/api-reference/volumes/search-volumes) +**Client SLA search → REST rent (minimum):** Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below (`misc` covers bundles search). + +```json +{ + "api": { + "misc": {}, + "instance_write": {}, + "instance_read": {} + } +} +``` + +Published OpenAPI charge `type` values for `GET /api/v0/charges/` are `gpu`, `disk`, `bwd`, and `bwu`. Prefer **Account → Billing** in the console for SLA settlement credit reconciliation until client charge schemas document SLA line items. + ### team\_read - [Show Team Members](/api-reference/team/show-team-members) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index fa3d277f..97fc9255 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -157,6 +157,11 @@ vastai search offers 'cpu_arch=arm64' | `expected_reliability` | float | host’s advertised SLA reliability claim on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | | `target_reliability` | float | desired SLA coverage (0–1 exclusive); prices `dph_total` in search only — see [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers) to enable at rent | + + +SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Older CLI builds may print a stderr warning that a field is unrecognized while still applying the filter — prefer a current CLI, or ignore the warning when results look correct. + + | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 332c0db5..1efdb0b3 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -179,7 +179,7 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and preferably `instance_read` (verify show-instances). See [Authentication](/api-reference/authentication) and [Permissions](/api-reference/permissions). -**3. Verify** via `GET /api/v1/instances/` or `vastai show instances --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. `GET /api/v1/instances/` returns at most 25 instances per request — paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. +**3. Verify** via `GET /api/v1/instances/` or `vastai show instances --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. Pass an explicit `limit` (default can be as low as **5**; maximum **25** per request). Paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. | Symptom | Typical response | What to do | | --- | --- | --- | @@ -310,7 +310,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta **Console:** After UTC settlement, open **Account → Billing** and look for SLA credit line items alongside compute charges. -**API:** SLA settlement credits are **not** exposed in `GET /api/v0/charges/` today (documented charge `type` values: `gpu`, `disk`, `bwd`, `bwu`). Use the console for reconciliation until a client billing endpoint documents SLA settlement rows. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. +**API:** Prefer **Account → Billing** for SLA settlement credit reconciliation. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. ## Related documentation diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index ed9df6e9..045e0a2e 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -199,9 +199,9 @@ If you have raised the pricing, you cannot extend the current rental contracts. It is vital to test your own machine to ensure the ports and software are running smoothly. -### Setup a separate client account +### Set up a separate client account -There are two supported ways to test your own machine. If you want to use the website GUI, you will need to setup a new account on a different email address, add a credit card and then find your machine and create instances on it like a client. This has the benefit of showing you the entire client experience. Testing the recommended Pytorch template is vital to ensure that SSH and Jupyter are working properly. +There are two supported ways to test your own machine. If you want to use the website GUI, you will need to set up a new account on a different email address, add a credit card and then find your machine and create instances on it like a client. This has the benefit of showing you the entire client experience. Testing the recommended PyTorch template is vital to ensure that SSH and Jupyter are working properly. ### Use the CLI (preferred) From ef425d9ac069fd121acbfd44e943e443a0951e11 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 28 Jul 2026 09:28:49 -0700 Subject: [PATCH 045/250] fix(openapi): rebuild combined OpenAPI to sync CI Regenerate openapi.yaml so nullable types and unique operationIds match the yaml sources and pass verify-openapi / mint openapi-check. Co-authored-by: Cursor --- api-reference/openapi.yaml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index c22d172f..383d1e6e 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8430,22 +8430,25 @@ paths: when applicable). example: 0.8021 target_reliability: - type: number + type: + - number + - 'null' format: float - nullable: true description: Client SLA coverage target locked at rent time. Null or 0 when the rental has no SLA. example: 0.95 sla_r_claim: - type: number + type: + - number + - 'null' format: float - nullable: true description: Host reliability claim for this SLA contract. example: 0.99 sla_sigma_x: - type: number + type: + - number + - 'null' format: float - nullable: true description: Host confidence spread for this SLA contract. example: 0.5 dlperf: @@ -9378,9 +9381,10 @@ paths: type: number format: float reliability: - type: number + type: + - number + - 'null' format: float - nullable: true beta: type: number format: float @@ -9476,7 +9480,6 @@ paths: description: "Too Many Requests \u2014 rate limit exceeded" tags: - Host - operationId: slaBacktest /api/v0/deployment/{id}/start: post: summary: start deployment From 1f438e9eedec33d16aaa8006370f8fd86f2f9a8f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 12:01:29 -0700 Subject: [PATCH 046/250] docs(sla): address doc-review consensus (cycle 1) Move the search-offers SLA note out of the field table, add scoped-key wayfinding, and align the backtester beta contract with omit-and-derive. Co-authored-by: Cursor --- api-reference/openapi.yaml | 4 ++-- api-reference/openapi/yaml/sla_backtest.yaml | 2 +- api-reference/permissions.mdx | 21 ++++++++++++++++---- cli/reference/search-offers.mdx | 9 ++++----- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 5 +++-- sdk/python/reference/create-instance.mdx | 21 +++++++++++++++++++- 7 files changed, 48 insertions(+), 16 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 383d1e6e..a5737a2a 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9331,10 +9331,10 @@ paths: schema: type: number format: float - default: 0.5 description: "Timescale mix used in settlement simulation. Not user-configurable\ \ for host API keys \u2014\nthe API derives weighting from `r` (recent vs\ - \ longer-term uptime). Omit this parameter.\n" + \ longer-term uptime). Omit this parameter.\nThe response `params.beta`\ + \ echoes the derived value.\n" responses: '200': description: Successful response diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index 542434a6..024eb4df 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -71,10 +71,10 @@ paths: schema: type: number format: float - default: 0.5 description: | Timescale mix used in settlement simulation. Not user-configurable for host API keys — the API derives weighting from `r` (recent vs longer-term uptime). Omit this parameter. + The response `params.beta` echoes the derived value. responses: '200': diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 24a21a7e..d6d39c0c 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -62,6 +62,11 @@ You can create scoped keys using: - **CLI**: [`vastai create api-key`](/cli/reference/create-api-key) - **SDK**: [`vast.create_api_key()`](/sdk/python/reference/create-api-key) +### SLA workflows (scoped keys) + +- **Hosts (list, backtest, earnings):** Minimum permissions: `machine_read`, `machine_write`, and `billing_read`. See [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe) under `machine_write`. [SLA Backtest](/api-reference/host/sla-backtest) is listed under `machine_read` and needs `machine_read` only for that call; listing and earnings still need the other two permissions. `machine_write` alone is not enough. +- **Clients (search → REST rent with SLA):** Minimum permissions: `misc`, `instance_read`, and `instance_write`. See [Client SLA scoped-key recipe](#client-sla-scoped-key-recipe) under `misc`. For console billing of SLA credits, use **Account → Billing** (not the charges API alone). + ## Custom Roles Custom roles let you assign the same set of permissions to multiple team members. @@ -194,7 +199,7 @@ Below is the complete mapping of which endpoints each permission category contro - [Show Machines](/api-reference/machines/show-machines) - [Show Reports](/api-reference/machines/show-reports) -- [SLA Backtest](/api-reference/host/sla-backtest) — API-only (hosts): replay historical earnings through SLA math. Requires `machine_read`. See [SLA Backtester](/host/sla-backtester). Console hosts should use **Set Pricing → SLA** preview instead. +- [SLA Backtest](/api-reference/host/sla-backtest) — API-only (hosts): replay historical earnings through SLA math. Requires `machine_read`. See [SLA Backtester](/host/sla-backtester). Console hosts should use the **Set Pricing → SLA** preview instead. Host SLA automation also requires `machine_write` and `billing_read`; see the [host SLA recipe](#host-sla-scoped-key-recipe) under `machine_write`. ### machine\_write @@ -208,7 +213,9 @@ Below is the complete mapping of which endpoints each permission category contro - [Unlist Machine](/api-reference/machines/unlist-machine) - [Unlist Volume](/api-reference/volumes/unlist-volume) -**Host SLA scoped-key recipe (minimum):** Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. + + +**Host only — minimum SLA API key.** Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. This key is for listing, backtest, and earnings — not a write-only listing key. ```json { @@ -240,7 +247,9 @@ Below is the complete mapping of which endpoints each permission category contro - [Search Offers](/api-reference/search/search-offers) - [Search Volumes](/api-reference/volumes/search-volumes) -**Client SLA search → REST rent (minimum):** Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below (`misc` covers bundles search). + + +**Client (renter) only — search and REST rent.** Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below (`misc` covers bundle search / the bundles search API). ```json { @@ -252,7 +261,11 @@ Below is the complete mapping of which endpoints each permission category contro } ``` -Published OpenAPI charge `type` values for `GET /api/v0/charges/` are `gpu`, `disk`, `bwd`, and `bwu`. Prefer **Account → Billing** in the console for SLA settlement credit reconciliation until client charge schemas document SLA line items. +**SLA settlement credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. + + +OpenAPI documents charge `type` values only; do not use this endpoint alone to reconcile SLA credits. + ### team\_read diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 97fc9255..ef35280d 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -157,11 +157,6 @@ vastai search offers 'cpu_arch=arm64' | `expected_reliability` | float | host’s advertised SLA reliability claim on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | | `target_reliability` | float | desired SLA coverage (0–1 exclusive); prices `dph_total` in search only — see [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers) to enable at rent | - - -SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Older CLI builds may print a stderr warning that a field is unrecognized while still applying the filter — prefer a current CLI, or ignore the warning when results look correct. - - | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | @@ -171,6 +166,10 @@ SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are acc | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | + +SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable SLA coverage at rent time; use the console or REST create-instance flow documented in [SLA Coverage](/guides/instances/choosing/sla-coverage). Older CLI builds may print a stderr warning that a field is unrecognized while still applying the filter — prefer a current CLI, or ignore the warning when results look correct. + + ## Global Options The following options are available for all commands: diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index eac84b9c..3e2fb975 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -91,7 +91,7 @@ Requires Bearer authentication. This endpoint is rate-limited like other host AP | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | | `reliability` | No | Optional flat uptime override (greater than 0 and at most 1). Ignores historical uptime — useful for what-if analysis. Use `0.01` to approximate near-total downtime; `0` is rejected with `400 bad_request`. | -| `beta` | No | Not user-configurable — the API derives timescale weighting from `r`. | +| `beta` | No | Not user-configurable — omit it. The API derives timescale weighting from `r` and echoes the value used in `params.beta` (the sample response shows `0.5`). Do not send a constant default. | ### Limits diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 78c1e9aa..65ba6696 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -549,8 +549,9 @@ On Windows, use WSL or the API example below. See [`show earnings`](/cli/referen **Linux (GNU date) — one UTC day (compare to `worst_day_loss`):** ```bash -vastai show earnings --machine_id --start_date $(date -u -d 'yesterday' +%F) --end_date $(date -u -d 'yesterday' +%F) --raw \ - | jq '.per_machine[] | select(.machine_id == or .machine_id == "") | {machine_id, sla_earn}' +# Replace 12345 with your machine ID. +vastai show earnings --machine_id 12345 --start_date $(date -u -d 'yesterday' +%F) --end_date $(date -u -d 'yesterday' +%F) --raw \ + | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` Positive `sla_earn` = net SLA charge you kept that period; negative = net credit you owe. Weekly aggregates are window totals, not daily series — use a one-day range above for day-level checks. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index c03ab4f4..5a0cda6a 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -173,6 +173,25 @@ VastAI.create_instance( from vastai import VastAI client = VastAI(api_key="YOUR_API_KEY") -result = client.create_instance(id=12345) +result = client.create_instance( + id=12345, # offer/ask ID from search, not a running instance ID + image="pytorch/pytorch:latest", + disk=50, +) print(result) ``` + +**SLA via REST:** `create_instance()` cannot set `target_reliability`. To enable coverage, rent with REST and pass the same target you searched with: + +```bash +curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "image": "pytorch/pytorch:latest", + "disk": 50, + "target_reliability": 0.95 + }' +``` + +See [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation). From 54e1944e4472c20ef733c07b004b69f129a1cbd8 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 12:05:27 -0700 Subject: [PATCH 047/250] docs(sla): address doc-review consensus (cycle 2) Clarify search machine_id and create-instance new_contract so offer, contract, and instance IDs stay distinct, and point API renters at console billing for SLA credits. Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index e71bbe2c..119f498f 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -157,7 +157,7 @@ vastai create instance 5801802 --image pytorch/pytorch --disk 40 --onstart-cmd ' vastai create instance 384826 --template_hash 661d064bbda1f2a133816b6d55da07c3 --disk 64 --bid_price 0.1 ``` -Return value — JSON reporting the instance ID of the newly created instance: +Return value — JSON with `new_contract`, the rental contract ID for the new instance. Use this value in the console **Instances** list, with `vastai show instances`, and with `GET /api/v1/instances/` as the instance `id`. It is not the search offer/ask `id` you passed to create-instance. ```json {"success": true, "new_contract": 7835610} diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index ef35280d..4079f1a1 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -147,7 +147,7 @@ vastai search offers 'cpu_arch=arm64' | `inet_down_cost` | float | internet download bandwidth cost in $/GB | | `inet_up` | float | internet upload speed in Mb/s | | `inet_up_cost` | float | internet upload bandwidth cost in $/GB | -| `machine_id` | int | machine id of instance | +| `machine_id` | int | Host machine ID (provider hardware). Use it to find offers from a specific host machine — not the offer/ask `id` and not your rental contract ID (`new_contract`) | | `min_bid` | float | current minimum bid price in $/hr for interruptible | | `num_gpus` | int | number of GPUs | | `pci_gen` | float | PCIE generation | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 1efdb0b3..a6f98392 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -181,6 +181,8 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe **3. Verify** via `GET /api/v1/instances/` or `vastai show instances --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. Pass an explicit `limit` (default can be as low as **5**; maximum **25** per request). Paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. +**Billing reconciliation (console):** confirming coverage does not show SLA settlement credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. + | Symptom | Typical response | What to do | | --- | --- | --- | | Target on a non-SLA offer | HTTP 400 `invalid_args` | Search with `has_sla=true`; confirm `expected_reliability` | From 50c2202825fe8d4f181dea24017bd1f53783942c Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 12:09:34 -0700 Subject: [PATCH 048/250] docs(sla): address doc-review consensus (cycle 3) Document new_contract on the Python create-instance return, and tell renters where maintenance credits are not visible and which reliability field to send. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 4 +++- sdk/python/reference/create-instance.mdx | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index a6f98392..b4833a8f 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -141,6 +141,8 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d Console-only renters can skip this section — use [In the web console](#in-the-web-console) above. +Renters set **`target_reliability`** on search and on REST rent. **`sla_r_target`** is a stored field name in some instance filters — do not send it in the rent body. + **Billing reconciliation:** SLA settlement credits appear in the console billing UI today. They are not included in `GET /api/v0/charges/` and client webhooks for SLA credits are not available — plan manual console reconciliation after UTC settlement (see [FAQ](#where-do-i-see-historical-sla-credits)). **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable): @@ -226,7 +228,7 @@ Each day, the platform tracks how long your instance was online. Settlement cons - A pattern of unreliable uptime produces larger credits over time. - One strong day after a weak week does not instantly reset everything. -Scheduled maintenance with adequate advance notice (typically 24+ hours) may be credited toward reliability on a case-by-case basis. Check **Instances** status and any client notifications during downtime to distinguish planned maintenance from an unexpected outage. Unplanned outages count fully. +Scheduled maintenance with adequate advance notice (typically 24+ hours) may be credited toward reliability on a case-by-case basis. Check **Instances** status and any client notifications during downtime to distinguish planned maintenance from an unexpected outage. Credited maintenance is not a separate field on instance webhooks or `GET /api/v0/charges/`. Unplanned outages count fully. ### Credit scenarios (simplified) diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 5a0cda6a..36c1f686 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -165,7 +165,7 @@ VastAI.create_instance( ## Returns -`dict` +`dict`. On success, the response includes `new_contract` — the rental contract / instance ID to use with show, destroy, and `GET /api/v1/instances/`. The `id` you pass to `create_instance()` is the offer/ask ID from search, not `new_contract`. `create_instance()` cannot set `target_reliability`; use REST for SLA coverage. ## Example From 2d44fb5bc79458fb08e0a1d0a4a790fe18c1dbc9 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 12:14:12 -0700 Subject: [PATCH 049/250] docs(sla): address doc-review consensus (cycle 4) State that SLA credits stay in console billing, require instance_read to verify coverage, and point CLI listings at the REST read-merge-PUT path. Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 5 ++++- host/sla-offers.mdx | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 119f498f..a6f2f6e1 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -129,7 +129,7 @@ vastai create instance ID [OPTIONS] [--args ...] ## Description -Performs the same action as pressing the "RENT" button on the website at https://console.vast.ai/create/ +Performs the same action as pressing the "RENT" button on the website at https://cloud.vast.ai/create/ Creates an instance from an offer ID (which is returned from "search offers"). Each offer ID can only be used to create one instance. Besides the offer ID, you must pass in an '`--image`' argument as a minimum. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b4833a8f..bde6b52e 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -24,6 +24,7 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing | I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances --raw` (`target_reliability` > 0). To enable coverage, use the console or [API automation](#api-automation) (REST) | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | | Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** SLA settlement credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | +| View SLA settlement credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). @@ -141,6 +142,8 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d Console-only renters can skip this section — use [In the web console](#in-the-web-console) above. +CLI and SDK `create instance` cannot set `target_reliability`. After a CLI/SDK search, finish rent in the console (Reliability target, then confirm an SLA charge line) or use the REST example below. If the instance has no SLA charge line, you do not have coverage. + Renters set **`target_reliability`** on search and on REST rent. **`sla_r_target`** is a stored field name in some instance filters — do not send it in the rent body. **Billing reconciliation:** SLA settlement credits appear in the console billing UI today. They are not included in `GET /api/v0/charges/` and client webhooks for SLA credits are not available — plan manual console reconciliation after UTC settlement (see [FAQ](#where-do-i-see-historical-sla-credits)). @@ -179,7 +182,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ See [Create Instance](/api-reference/instances/create-instance) and [Search Offers](/api-reference/search/search-offers). -**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and preferably `instance_read` (verify show-instances). See [Authentication](/api-reference/authentication) and [Permissions](/api-reference/permissions). +**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). **3. Verify** via `GET /api/v1/instances/` or `vastai show instances --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. Pass an explicit `limit` (default can be as low as **5**; maximum **25** per request). Paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 65ba6696..e1241972 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -280,7 +280,7 @@ vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12 Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. -Then `PUT /api/v0/machines/create_asks/` with merged fields. +Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge → PUT). `vastai list machine` and the Python SDK listing helpers cannot set SLA fields; start from this REST pattern (or the console) when you move an existing CLI listing to SLA. ### Fleet listing workflow (advanced — fleet operators only) From 017bf7ee73f08e0c30e85c140f7dfd9fb6276d98 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 12:23:56 -0700 Subject: [PATCH 050/250] docs(sla): address doc-review consensus (cycle 6) Point SLA verification at show instances-v1, matching the v1 instances API, and finish the incomplete post-rent comparison sentence. Co-authored-by: Cursor --- api-reference/openapi.yaml | 2 +- api-reference/openapi/yaml/show_instances.yaml | 2 +- cli/reference/create-instance.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 10 +++++----- sdk/python/reference/create-instance.mdx | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index a5737a2a..84b60f05 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8061,7 +8061,7 @@ paths: and sorting. - CLI Usage: `vastai show instances [OPTIONS] [--api-key API_KEY] [--raw]`' + CLI Usage: `vastai show instances-v1 [OPTIONS] [--api-key API_KEY] [--raw]`' security: - BearerAuth: [] parameters: diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index c2f0a921..9da55b8a 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -14,7 +14,7 @@ paths: Retrieve a paginated list of instances for the authenticated user. Supports keyset pagination (max 25 per page), filtering, column selection, and sorting. - CLI Usage: `vastai show instances [OPTIONS] [--api-key API_KEY] [--raw]` + CLI Usage: `vastai show instances-v1 [OPTIONS] [--api-key API_KEY] [--raw]` security: - BearerAuth: [] parameters: diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index a6f2f6e1..14229441 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -157,7 +157,7 @@ vastai create instance 5801802 --image pytorch/pytorch --disk 40 --onstart-cmd ' vastai create instance 384826 --template_hash 661d064bbda1f2a133816b6d55da07c3 --disk 64 --bid_price 0.1 ``` -Return value — JSON with `new_contract`, the rental contract ID for the new instance. Use this value in the console **Instances** list, with `vastai show instances`, and with `GET /api/v1/instances/` as the instance `id`. It is not the search offer/ask `id` you passed to create-instance. +Return value — JSON with `new_contract`, the rental contract ID for the new instance. Use this value in the console **Instances** list and with `GET /api/v1/instances/` as the instance `id` (`vastai show instances-v1 --raw` for v1 fields). It is not the search offer/ask `id` you passed to create-instance. ```json {"success": true, "new_contract": 7835610} diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index bde6b52e..3ec5d2dc 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -21,7 +21,7 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing | Goal | Start here | | --- | --- | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | -| I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances --raw` (`target_reliability` > 0). To enable coverage, use the console or [API automation](#api-automation) (REST) | +| I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances-v1 --raw` (`target_reliability` > 0). To enable coverage, use the console or [API automation](#api-automation) (REST) | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | | Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** SLA settlement credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | | View SLA settlement credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | @@ -182,9 +182,9 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ See [Create Instance](/api-reference/instances/create-instance) and [Search Offers](/api-reference/search/search-offers). -**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). +**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). -**3. Verify** via `GET /api/v1/instances/` or `vastai show instances --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. Pass an explicit `limit` (default can be as low as **5**; maximum **25** per request). Paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. +**3. Verify** via `GET /api/v1/instances/` or `vastai show instances-v1 --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. Pass an explicit `limit` (default can be as low as **5**; maximum **25** per request). Paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. On the CLI, use `--limit` and `--next-token` with `show instances-v1`. **Billing reconciliation (console):** confirming coverage does not show SLA settlement credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. @@ -208,7 +208,7 @@ See [Create Instance](/api-reference/instances/create-instance) and [Search Offe When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target, the host's claim, and host confidence (how the host priced SLA around their claim) are fixed for that rental. You only compare the SLA charge or `dph_total` — confidence is a host-side pricing knob, not a setting you control. +1. **Contract terms lock in** — your reliability target, the host's claim, and host confidence (how the host priced SLA around their claim) are fixed for that rental. When comparing offers, use the SLA charge line or `dph_total`. Host confidence is not shown in the client UI and is not a setting you control. 2. **Daily billing** — you pay compute plus the SLA charge each day. 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — settlement credits improve your balance; strong days mean you paid the SLA charge with no credit. @@ -274,7 +274,7 @@ Production settlement uses the multi-window reliability blend described above, n ### API integrators -Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. (CLI can **read** these fields via `vastai show instances --raw`; enabling SLA still requires console or REST — see [Finding SLA offers](#finding-sla-offers).) +Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. (CLI can **read** these fields via `vastai show instances-v1 --raw`; enabling SLA still requires console or REST — see [Finding SLA offers](#finding-sla-offers).)
API integrators: field names and filters diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 36c1f686..b579c517 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -165,7 +165,7 @@ VastAI.create_instance( ## Returns -`dict`. On success, the response includes `new_contract` — the rental contract / instance ID to use with show, destroy, and `GET /api/v1/instances/`. The `id` you pass to `create_instance()` is the offer/ask ID from search, not `new_contract`. `create_instance()` cannot set `target_reliability`; use REST for SLA coverage. +`dict`. On success, the response includes `new_contract` — the rental contract / instance ID to use with destroy and `GET /api/v1/instances/` (`vastai show instances-v1`). The `id` you pass to `create_instance()` is the offer/ask ID from search, not `new_contract`. `create_instance()` cannot set `target_reliability`; use REST for SLA coverage. ## Example From d88c84945fb3bad3b86f9c8867c3334bdc7ae24d Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 14:02:08 -0700 Subject: [PATCH 051/250] docs(sla): address doc-review consensus (cycle 7) Split host and client scoped-key guidance, name the create-instance argument as an offer ID, and pin the SLA rent image example. Co-authored-by: Cursor --- api-reference/permissions.mdx | 9 ++++++--- guides/instances/choosing/sla-coverage.mdx | 2 +- sdk/python/reference/create-instance.mdx | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index d6d39c0c..c539dea7 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -64,8 +64,11 @@ You can create scoped keys using: ### SLA workflows (scoped keys) -- **Hosts (list, backtest, earnings):** Minimum permissions: `machine_read`, `machine_write`, and `billing_read`. See [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe) under `machine_write`. [SLA Backtest](/api-reference/host/sla-backtest) is listed under `machine_read` and needs `machine_read` only for that call; listing and earnings still need the other two permissions. `machine_write` alone is not enough. -- **Clients (search → REST rent with SLA):** Minimum permissions: `misc`, `instance_read`, and `instance_write`. See [Client SLA scoped-key recipe](#client-sla-scoped-key-recipe) under `misc`. For console billing of SLA credits, use **Account → Billing** (not the charges API alone). +**Renters (clients):** Use client scopes only: `misc`, `instance_read`, and `instance_write`. Start with [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation), then the [Client SLA scoped-key recipe](#client-sla-scoped-key-recipe). Do not copy the host recipe. + +**Hosts (providers):** Use host scopes: `machine_read`, `machine_write`, and `billing_read`. `machine_read` alone covers backtest; listing and earnings also need `machine_write` and `billing_read`. See the [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe). Do not copy the client recipe. + +`misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). SLA settlement credits stay in the console (**Account → Billing**), not the Charges API. ## Custom Roles @@ -249,7 +252,7 @@ Below is the complete mapping of which endpoints each permission category contro -**Client (renter) only — search and REST rent.** Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below (`misc` covers bundle search / the bundles search API). +**Client (renter) only — search and REST rent.** Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). ```json { diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 3ec5d2dc..92e3fbd6 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -174,7 +174,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "image": "pytorch/pytorch:latest", + "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", "disk": 50, "target_reliability": 0.95 }' diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index b579c517..cf0ad0da 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -3,7 +3,7 @@ title: "VastAI.create_instance" sidebarTitle: "create_instance" --- -Create a new instance from a contract offer ID. +Create a new instance from an offer/ask ID returned by search. **SLA coverage:** `target_reliability` is not available on `create_instance()` today. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable SLA — see [SLA Coverage](/guides/instances/choosing/sla-coverage#api-automation). @@ -175,7 +175,7 @@ from vastai import VastAI client = VastAI(api_key="YOUR_API_KEY") result = client.create_instance( id=12345, # offer/ask ID from search, not a running instance ID - image="pytorch/pytorch:latest", + image="pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", disk=50, ) print(result) @@ -188,7 +188,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "image": "pytorch/pytorch:latest", + "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", "disk": 50, "target_reliability": 0.95 }' From de4db0d5a03f76bec918f01e2bc8721d30232f24 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 14:07:57 -0700 Subject: [PATCH 052/250] docs(sla): explain SLA in plain language for hosts and renters Lead both guides with what the promise, fee, and credit actually are before field names and API paths. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 22 ++++++++++++++++++++++ host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 22 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 92e3fbd6..66c84725 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -8,6 +8,27 @@ Some Vast.ai offers include a **Service Level Agreement (SLA)** — a reliabilit This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. +## SLA in plain language + +An SLA is an optional reliability promise on an **on-demand** GPU rental. You do not have to use it. + +1. The **host** says how often they expect the machine to be up. That is their **claim**. +2. **You** choose how much uptime you want. That is your **target**. A higher target costs more. +3. You pay a small extra hourly fee, the **SLA charge**, on top of the GPU price. +4. Each day, Vast checks how long your instance was actually up. +5. If uptime met your target, the host keeps that fee. +6. If uptime missed your target, you get money back as a **credit** on your account. That credit can be larger than the fee you paid that day. + +A few things people mix up: + +- The **reliability score** on an offer card is a separate marketplace signal. It is not your SLA. +- The GPU bill does **not** stop during an outage. SLA pays you back later as a credit, usually after the next UTC midnight. +- A search filter does **not** buy coverage. You have to set a reliability target when you rent, in the web console or with the API. The CLI cannot turn SLA on today. +- SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. +- If the price breakdown has **no SLA charge line**, you do not have coverage. + +Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). + **SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via the **REST API**, pass `target_reliability` on **create-instance** (`PUT /api/v0/asks/{id}/`). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. @@ -20,6 +41,7 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing | Goal | Start here | | --- | --- | +| Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | | I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances-v1 --raw` (`target_reliability` > 0). To enable coverage, use the console or [API automation](#api-automation) (REST) | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 045e0a2e..8a396124 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -49,7 +49,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (uptime guarantee):** Optional add-on for on-demand listings. You set a **Claim** (reliability you believe you can deliver) and **Confidence** (how tightly SLA charges are priced around that claim). Clients choose their own reliability **target** at search/rent time. Start with [How it works (plain English)](/host/sla-offers#how-it-works-plain-english), then read the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. Renters: see [SLA Coverage](/guides/instances/choosing/sla-coverage). +- **SLA (uptime guarantee):** Optional add-on for on-demand listings. In short: you state a reliability **claim**, the renter picks a **target**, they pay a small extra hourly fee, and if uptime misses that target they get a credit from your earnings. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language), then the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. Renters: [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e1241972..1a377eed 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -20,6 +20,7 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative | Goal | Start here | | --- | --- | +| Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | | Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer). Planned downtime during active rentals still needs [CLI/REST schedule maint](#scheduled-maintenance) — no in-console scheduler. | | Enable or update SLA via API | [Before you enable SLA](#before-you-enable-sla) → [API (for automation)](#api-for-automation) | | I list with CLI only (no SLA flags yet) | **Set Pricing → SLA** + **LIST** in the console, or REST `PUT /api/v0/machines/create_asks/` — SLA flags are **not** in `vastai list machine` yet | @@ -64,6 +65,27 @@ On outage days you may still bill clients for **intended** compute **and** owe S - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. - **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting `worst_day_loss`. Consider wider confidence or a more conservative claim until you have a few weeks of data. +## SLA in plain language + +SLA is an optional reliability promise on **on-demand** rentals. You do not have to offer it. + +1. **You (the host)** say how often you expect the machine to be up. That is your **claim**. +2. You also say how sure you are of that claim. That is your **confidence**. Tighter confidence makes the renter's extra fee smaller. +3. The **renter** picks how much uptime they want. That is their **target**. You do not set their target. +4. The renter pays a small extra hourly fee, the **SLA charge**, on top of the GPU price. +5. Each day, Vast checks how long that rental was actually up. +6. If uptime met their target, you keep the fee. +7. If uptime missed their target, the renter gets a **credit** from your earnings. One bad day can cost more than many days of fees. + +What this is not: + +- It is not the reliability score on the offer card. +- Listing the machine does not turn SLA on. You turn it on in **Set Pricing → SLA** (or with the listing API). The CLI `list machine` command cannot set it today. +- It applies only to **on-demand** rentals, not interruptible or reserved ones. +- An outage does not erase that day's GPU bill. The renter's compensation is a separate credit. + +The field names for claim, confidence, and target are in [How it works (plain English)](#how-it-works-plain-english) below. Renters get the same story in [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). + ## How it works (plain English) From 8d6ecc95746982f3b19568a6ecc520d929ceb025 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 14:13:13 -0700 Subject: [PATCH 053/250] docs(sla): address doc-review consensus (cycle 9) Say when extra key scopes are needed, show a template rent body, and point CLI search at the SLA premium field. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 ++++ cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 17 ++++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index c539dea7..b839cc68 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -237,6 +237,8 @@ Below is the complete mapping of which endpoints each permission category contro | Schedule / cancel maintenance | `machine_write` | None (CLI/REST only) | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | +Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Search verification (`vastai search offers`) needs `misc` as well; the console Machines page does not. + ### misc - [Show Workergroups](/api-reference/serverless/show-workergroup) @@ -264,6 +266,8 @@ Below is the complete mapping of which endpoints each permission category contro } ``` +This is the minimum for search, REST rent, and verify. Add `user_read` if the flow loads templates or account profile data, and `user_write` if it creates SSH keys or templates. See the instance-management example under [Creating Scoped Keys](#creating-scoped-keys). + **SLA settlement credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 4079f1a1..7bae896f 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -167,7 +167,7 @@ vastai search offers 'cpu_arch=arm64' | `vms_enabled` | bool | is the machine a VM instance | -SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable SLA coverage at rent time; use the console or REST create-instance flow documented in [SLA Coverage](/guides/instances/choosing/sla-coverage). Older CLI builds may print a stderr warning that a field is unrecognized while still applying the filter — prefer a current CLI, or ignore the warning when results look correct. +SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable SLA coverage at rent time; use the console or REST create-instance flow documented in [SLA Coverage](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA premium for that quote is `search.slaPremiumPerHour` — see [SLA Coverage → Finding SLA offers](/guides/instances/choosing/sla-coverage#finding-sla-offers). Older CLI builds may print a stderr warning that a field is unrecognized while still applying the filter — prefer a current CLI, or ignore the warning when results look correct. ## Global Options diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 66c84725..5a655651 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with reliability guarantees. Learn how SLA char "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — a reliability guarantee you can add to an **on-demand** rental. You choose a reliability **target** when you search, pay a small hourly **SLA charge** on top of compute, and if measured reliability falls short of that target, you receive settlement credits. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay a small hourly **SLA charge** only after you set a reliability **target** at rent time. If measured uptime falls short of that target, you receive a settlement credit. Search can quote the price; it does not turn coverage on by itself. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -204,6 +204,21 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ See [Create Instance](/api-reference/instances/create-instance) and [Search Offers](/api-reference/search/search-offers). +**Rent with a template** (the template supplies the image; still send the same target and enough disk): + +```bash +curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "template_hash_id": "YOUR_TEMPLATE_HASH", + "disk": 50, + "target_reliability": 0.95 + }' +``` + +`template_hash_id` is the content hash of a saved template. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). + **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). **3. Verify** via `GET /api/v1/instances/` or `vastai show instances-v1 --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. Pass an explicit `limit` (default can be as low as **5**; maximum **25** per request). Paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. On the CLI, use `--limit` and `--next-token` with `show instances-v1`. From c6a3c65ee19eef9febd3904d7bfaa03512867e19 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 14:17:33 -0700 Subject: [PATCH 054/250] docs(sla): address doc-review consensus (cycle 10) Include misc on the host SLA key so copied recipes can verify listings with search offers. Co-authored-by: Cursor --- api-reference/permissions.mdx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b839cc68..0b185a60 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -66,7 +66,7 @@ You can create scoped keys using: **Renters (clients):** Use client scopes only: `misc`, `instance_read`, and `instance_write`. Start with [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation), then the [Client SLA scoped-key recipe](#client-sla-scoped-key-recipe). Do not copy the host recipe. -**Hosts (providers):** Use host scopes: `machine_read`, `machine_write`, and `billing_read`. `machine_read` alone covers backtest; listing and earnings also need `machine_write` and `billing_read`. See the [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe). Do not copy the client recipe. +**Hosts (providers):** Use host scopes: `machine_read`, `machine_write`, and `billing_read`. Add `misc` if you verify the listing with search offers. `machine_read` alone covers backtest; listing and earnings also need `machine_write` and `billing_read`. See the [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe). Do not copy the client recipe. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). SLA settlement credits stay in the console (**Account → Billing**), not the Charges API. @@ -225,19 +225,23 @@ Below is the complete mapping of which endpoints each permission category contro "api": { "machine_read": {}, "machine_write": {}, - "billing_read": {} + "billing_read": {}, + "misc": {} } } ``` +`misc` is required for `vastai search offers` / `POST /api/v0/bundles/`. Omit it if you only check the listing in the console. + | Task | Permission | Console fallback | | --- | --- | --- | | List/update SLA via `create_asks` | `machine_write` | **Set Pricing → SLA** → LIST | | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | None (CLI/REST only) | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | +| Verify the listing in search | `misc` | **Host → Machines** (no API key) | -Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Search verification (`vastai search offers`) needs `misc` as well; the console Machines page does not. +Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. ### misc From f6d281a7a8be7b778d8adec2683f99e941753329 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Tue, 29 Sep 2026 14:20:46 -0700 Subject: [PATCH 055/250] docs(sla): address doc-review consensus (cycle 11) State who needs a scoped key, and give REST readers a short prerequisite and rate-limit gate before the automation steps. Co-authored-by: Cursor --- api-reference/permissions.mdx | 10 ++++++---- guides/instances/choosing/sla-coverage.mdx | 8 ++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 0b185a60..e661d69c 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -64,11 +64,13 @@ You can create scoped keys using: ### SLA workflows (scoped keys) -**Renters (clients):** Use client scopes only: `misc`, `instance_read`, and `instance_write`. Start with [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation), then the [Client SLA scoped-key recipe](#client-sla-scoped-key-recipe). Do not copy the host recipe. +**Console-only users** do not need a scoped API key to rent or list with SLA. These recipes are for REST and CLI automation. -**Hosts (providers):** Use host scopes: `machine_read`, `machine_write`, and `billing_read`. Add `misc` if you verify the listing with search offers. `machine_read` alone covers backtest; listing and earnings also need `machine_write` and `billing_read`. See the [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe). Do not copy the client recipe. +**Renters (clients):** Use the [client SLA recipe](#client-sla-scoped-key-recipe) only — `misc`, `instance_read`, and `instance_write` together. Start with [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). Do not copy the host recipe. -`misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). SLA settlement credits stay in the console (**Account → Billing**), not the Charges API. +**Hosts (providers):** Use every category in the [host SLA recipe](#host-sla-scoped-key-recipe). `machine_write` by itself is not enough. Add `misc` if you verify the listing with search offers. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). Do not copy the client recipe. + +On this page, **client** means renter and **provider** means host. ## Custom Roles @@ -218,7 +220,7 @@ Below is the complete mapping of which endpoints each permission category contro -**Host only — minimum SLA API key.** Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. This key is for listing, backtest, and earnings — not a write-only listing key. +**Host only — minimum SLA API key.** Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. Enable every category in the JSON below. `machine_write` by itself cannot backtest, list, and read earnings. ```json { diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 5a655651..287e160d 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -162,9 +162,13 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d ### API automation -Console-only renters can skip this section — use [In the web console](#in-the-web-console) above. +**Prerequisites:** You should be comfortable with REST, an API key, and JSON. Otherwise stay on [In the web console](#in-the-web-console). Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm coverage on the instance. -CLI and SDK `create instance` cannot set `target_reliability`. After a CLI/SDK search, finish rent in the console (Reliability target, then confirm an SLA charge line) or use the REST example below. If the instance has no SLA charge line, you do not have coverage. +Console-only renters can skip the rest of this section. + +CLI and SDK `create instance` cannot set `target_reliability`. After a CLI/SDK search, complete the rental in the console (set Reliability target, then confirm an SLA charge line) or use the REST example below. If the instance has no SLA charge line, you do not have coverage. + +For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Renters set **`target_reliability`** on search and on REST rent. **`sla_r_target`** is a stored field name in some instance filters — do not send it in the rent body. From 5af43848ea2c9d6fd44b8923dedee4e83dab778f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 08:27:31 -0700 Subject: [PATCH 056/250] docs(sla): align wording with legal terminology review Use SLA, reliability commitment, reliability target, SLA fee, and service credit in public docs while keeping API field names. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 10 +- guides/instances/choosing/find-and-rent.mdx | 10 +- guides/instances/choosing/sla-coverage.mdx | 94 +++++++-------- host/hosting-overview.mdx | 10 +- host/sla-backtester.mdx | 26 ++-- host/sla-offers.mdx | 124 ++++++++++---------- sdk/python/reference/create-instance.mdx | 8 +- snippets/host/cli/schedule-maint.mdx | 2 +- 10 files changed, 144 insertions(+), 144 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index e661d69c..b9642407 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -274,7 +274,7 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user This is the minimum for search, REST rent, and verify. Add `user_read` if the flow loads templates or account profile data, and `user_write` if it creates SSH keys or templates. See the instance-management example under [Creating Scoped Keys](#creating-scoped-keys). -**SLA settlement credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. +**service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. OpenAPI documents charge `type` values only; do not use this endpoint alone to reconcile SLA credits. diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 14229441..0017de99 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create instance" Create a new instance -**SLA coverage:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable SLA. See [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**SLA:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable SLA. See [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). ## Usage diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 7bae896f..fab93770 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -78,14 +78,14 @@ bool = True | False ## Examples -**Search quotes SLA pricing only.** `vastai create instance` cannot pass `target_reliability` today — use the web console or REST to enable coverage; see [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**Search quotes SLA pricing only.** `vastai create instance` cannot pass `target_reliability` today — use the web console or REST to enable the SLA; see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash # reliable single RTX 3090, no conflicts with stopped instances vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=False' -# SLA search quote (enable coverage at rent via console/REST — see SLA Coverage) +# SLA search quote (enable the SLA at rent via console/REST — see SLA) # Always set --storage explicitly when comparing dph_total (CLI default 5 GiB ≠ REST 8 GB). vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total @@ -154,9 +154,9 @@ vastai search offers 'cpu_arch=arm64' | `pcie_bw` | float | PCIE bandwidth (CPU to GPU) | | `dph_total` | float | total $/hr in search results (compute + storage + SLA charge when applicable) | | `reliability` | float | machine reliability score (see FAQ for explanation) | -| `expected_reliability` | float | host’s advertised SLA reliability claim on the offer | +| `expected_reliability` | float | host’s advertised SLA reliability commitment on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | -| `target_reliability` | float | desired SLA coverage (0–1 exclusive); prices `dph_total` in search only — see [SLA Coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers) to enable at rent | +| `target_reliability` | float | reliability target (0–1 exclusive); prices `dph_total` in search only — see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers) to enable the SLA at rent | | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | @@ -167,7 +167,7 @@ vastai search offers 'cpu_arch=arm64' | `vms_enabled` | bool | is the machine a VM instance | -SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable SLA coverage at rent time; use the console or REST create-instance flow documented in [SLA Coverage](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA premium for that quote is `search.slaPremiumPerHour` — see [SLA Coverage → Finding SLA offers](/guides/instances/choosing/sla-coverage#finding-sla-offers). Older CLI builds may print a stderr warning that a field is unrecognized while still applying the filter — prefer a current CLI, or ignore the warning when results look correct. +SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console or REST create-instance flow documented in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour` — see [SLA → Finding SLA offers](/guides/instances/choosing/sla-coverage#finding-sla-offers). Older CLI builds may print a stderr warning that a field is unrecognized while still applying the filter — prefer a current CLI, or ignore the warning when results look correct. ## Global Options diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index b28d2236..3a30cafa 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -54,11 +54,11 @@ All stats shown are the portion of the total machine rented. - Disk speed: The speed of the local storage on the machine in MB/s - Total available disk: The maximum amount of disk space available - DLPERF score: A custom deep learning performance score -- Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. On SLA listings, the breakdown also shows an **SLA charge** line — see [SLA Coverage](/guides/instances/choosing/sla-coverage). +- Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. On SLA listings, the breakdown also shows an **SLA charge** line — see [SLA](/guides/instances/choosing/sla-coverage). - Max Duration: The maximum length of a rental contract on this machine -- Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host SLA claim. +- Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host reliability commitment. - Rental Option: RENT button -- **SLA (optional):** On-demand offers may include an optional SLA upsell. The host’s advertised SLA claim (not the Reliability Score above) sets the ceiling for your target. Confirm an **SLA charge** line before **RENT** — see [SLA Coverage](/guides/instances/choosing/sla-coverage). +- **SLA (optional):** On-demand offers may include an optional SLA upsell. The host’s advertised reliability commitment (not the Reliability Score above) sets the ceiling for your target. Confirm an **SLA charge** line before **RENT** — see [SLA](/guides/instances/choosing/sla-coverage). ## Instance Disk Size @@ -66,7 +66,7 @@ The storage slider is both a search filter and a parameter input which determine When the instance is created, the disk size is set and cannot be modified. Estimate how much disk you need, then move the slider to that size. The default disk size in the console is 10GB. Hosts charge for disk allocation even when the instance is stopped. -If you compare prices across the console, CLI, and REST, match disk size first — defaults differ by channel. See [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation). +If you compare prices across the console, CLI, and REST, match disk size first — defaults differ by channel. See [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation). ![Diskspace](/images/find-and-rent-diskspace.webp) @@ -83,7 +83,7 @@ Click on the "Change Template" button to bring up the template config menu that ![Edit](/images/find-and-rent-edit.webp) -Some offers include an optional **SLA** reliability guarantee. To filter and compare SLA-backed rentals, see [SLA Coverage](/guides/instances/choosing/sla-coverage). +Some offers include an optional **SLA** reliability guarantee. To filter and compare SLA-backed rentals, see [SLA](/guides/instances/choosing/sla-coverage). ## Common Questions diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 287e160d..8953c815 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -1,10 +1,10 @@ --- -title: "SLA Coverage" -description: "Rent GPU instances with reliability guarantees. Learn how SLA charges, credits, and search filters work." +title: "SLA" +description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability target, and service credits work." "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay a small hourly **SLA charge** only after you set a reliability **target** at rent time. If measured uptime falls short of that target, you receive a settlement credit. Search can quote the price; it does not turn coverage on by itself. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay a small hourly **SLA fee** only after you set a **reliability target** at rent time. If measured uptime falls short of that target, you receive a **service credit**. Search can quote the price; it does not turn the SLA on by itself. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -12,20 +12,20 @@ This page explains SLA from the renter side: how to find SLA offers, how pricing An SLA is an optional reliability promise on an **on-demand** GPU rental. You do not have to use it. -1. The **host** says how often they expect the machine to be up. That is their **claim**. -2. **You** choose how much uptime you want. That is your **target**. A higher target costs more. -3. You pay a small extra hourly fee, the **SLA charge**, on top of the GPU price. +1. The **host** states a **reliability commitment**: how often they expect the machine to be up. +2. **You** choose a **reliability target**: how much uptime you want. A higher target costs more. +3. You pay an **SLA fee** (a service level fee) on top of the GPU price. 4. Each day, Vast checks how long your instance was actually up. -5. If uptime met your target, the host keeps that fee. -6. If uptime missed your target, you get money back as a **credit** on your account. That credit can be larger than the fee you paid that day. +5. If uptime met your reliability target, the host keeps the SLA fee. +6. If uptime missed your reliability target, you receive a **service credit**. That credit can be larger than the SLA fee you paid that day. A few things people mix up: - The **reliability score** on an offer card is a separate marketplace signal. It is not your SLA. - The GPU bill does **not** stop during an outage. SLA pays you back later as a credit, usually after the next UTC midnight. -- A search filter does **not** buy coverage. You have to set a reliability target when you rent, in the web console or with the API. The CLI cannot turn SLA on today. +- A search filter does **not** turn on an SLA. You have to set a reliability target when you rent, in the web console or with the API. The CLI cannot turn SLA on today. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. -- If the price breakdown has **no SLA charge line**, you do not have coverage. +- If the price breakdown has **no SLA fee line**, you do not have an SLA. Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). @@ -34,7 +34,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua -`target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Searching with a target only quotes pricing — use the **web console** or **REST** create-instance to enable coverage (see [Finding SLA offers](#finding-sla-offers)). +`target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Searching with a target only quotes pricing — use the **web console** or **REST** create-instance to enable the SLA (see [Finding SLA offers](#finding-sla-offers)). ## Choose your path @@ -43,28 +43,28 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | -| I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances-v1 --raw` (`target_reliability` > 0). To enable coverage, use the console or [API automation](#api-automation) (REST) | +| I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances-v1 --raw` (`target_reliability` > 0). To enable the SLA, use the console or [API automation](#api-automation) (REST) | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | -| Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** SLA settlement credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | -| View SLA settlement credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | +| Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | +| View service credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). -You do not post escrow or collateral for SLA. You pay the SLA charge while your rental contract is active (including during outages, before settlement credits are applied). Settlement happens automatically on a daily UTC cadence. +You do not post escrow or collateral for SLA. You pay the SLA charge while your rental contract is active (including during outages, before service credits are applied). Settlement happens automatically on a daily UTC cadence. ## What SLA protects SLA is a **contractual, per-rental** reliability guarantee with automatic daily settlement. It is **not** the same as verification or the **reliability score** on offer cards — those are platform trust signals (see [Machine Tiers](/guides/instances/choosing/find-and-rent#machine-tiers)). -For SLA-covered on-demand contracts: +For on-demand contracts with an SLA: - You are charged for **compute, storage, and the SLA charge** for the rental day, including periods when the instance is unavailable. - Offline time is tracked as an outage in reliability measurements. -- If you qualify for compensation, a **settlement credit** posts after daily settlement (UTC) — typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. +- If you qualify for compensation, a **service credit** posts after daily settlement (UTC) — typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. SLA is most useful for **long-running production workloads** where unexpected downtime has a real cost beyond the hourly rate. @@ -81,14 +81,14 @@ Bandwidth is billed separately from usage (`inet_*` rates) and is **not** includ | Factor | What it means for you | | --- | --- | | Your reliability target | Higher target → higher SLA charge | -| Host SLA claim | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher claim → lower SLA charge at a given target | +| Host reliability commitment | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher commitment → lower SLA fee at a given reliability target | | Host confidence | Host-side pricing setting that affects SLA charge size. **You do not set this** — the host chooses it, and it is **not shown on offer cards**. Compare offers using `dph_total` or the SLA charge line in the price breakdown | -**Rule of thumb:** pick a target **at or below** the host's claim for the best value. Asking for 99% coverage on a host who only claims 95% costs much more than asking for 95% on a host who claims 99%. In search results, the host claim appears as **expected reliability** / SLA claim on the offer (API: `expected_reliability`) — not the Reliability Score on the card. +**Rule of thumb:** pick a reliability target **at or below** the host's reliability commitment for the best value. Asking for a 99% reliability target on a host whose reliability commitment is only 95% costs much more than asking for 95% on a host whose reliability commitment is 99%. In search results, the host reliability commitment appears as **expected reliability** on the offer (API: `expected_reliability`) — not the Reliability Score on the card. ### Example: H100 at $3.50/hr GPU -Searching with **target reliability 95%** on an offer where the host **claims 99%** with normal confidence: +Searching with a **reliability target of 95%** on an offer where the host's **reliability commitment is 99%** with normal confidence: | Cost component | Approx. rate | | --- | --- | @@ -100,17 +100,17 @@ Searching with **target reliability 95%** on an offer where the host **claims 99 ## Finding SLA offers -**No SLA charge line in the price breakdown = no SLA coverage.** Filtering to SLA listings or searching with a reliability target only quotes pricing. Coverage requires setting **Reliability target** in the console (or passing `target_reliability` on REST create-instance) before you rent. +**No SLA fee line in the price breakdown means you do not have an SLA.** Filtering to SLA listings or searching with a reliability target only quotes pricing. The SLA starts only when you set **Reliability target** in the console (or pass `target_reliability` on REST create-instance) before you rent. -**Decision rule:** Search filters **quote** SLA pricing only. Coverage activates only when you rent via the **web console** (Reliability target set) or **REST** create-instance (`target_reliability` on `PUT /api/v0/asks/{id}/`). The CLI cannot enable SLA at rent time today — see [API automation](#api-automation) for the minimum REST rent path. +**Decision rule:** Search filters **quote** SLA pricing only. The SLA starts only when you rent via the **web console** (Reliability target set) or **REST** create-instance (`target_reliability` on `PUT /api/v0/asks/{id}/`). The CLI cannot enable the SLA at rent time today — see [API automation](#api-automation) for the minimum REST rent path. ### In the web console 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). -2. In Search filters (left filter bar), set **Reliability target** to your desired coverage level — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. -3. Optionally narrow results with an SLA-enabled / `has_sla` filter if shown. Filtering listings is **not** the same as enabling coverage. -4. Before you click **RENT**, confirm the price breakdown shows an **SLA charge** line. No SLA charge means no SLA coverage for that rental. +2. In Search filters (left filter bar), set **Reliability target** to your desired reliability target — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. +3. Optionally narrow results with an SLA-enabled / `has_sla` filter if shown. Filtering listings is **not** the same as enabling the SLA. +4. Before you click **RENT**, confirm the price breakdown shows an **SLA fee** line. No SLA fee line means that rental has no SLA. 5. Rent as usual. Your target is locked at rent time. CLI and API examples below use the same filters. @@ -121,16 +121,16 @@ CLI and API examples below use the same filters. | --- | --- | --- | | `target_reliability` | Your desired reliability level. Also drives SLA charge calculation and ranking. | `target_reliability=0.95` | | `has_sla` | Restrict to offers with (or without) SLA enabled. | `has_sla=true` | -| `expected_reliability` | Filter by the host's advertised claim. | `expected_reliability>=0.99` | +| `expected_reliability` | Filter by the host's advertised reliability commitment. | `expected_reliability>=0.99` | -**API integrators:** `reliability` is the historical machine score, not the host’s SLA claim. Use `has_sla=true` and/or `expected_reliability` to find SLA listings. +**API integrators:** `reliability` is the historical machine score, not the host’s reliability commitment. Use `has_sla=true` and/or `expected_reliability` to find SLA listings. **CLI examples:** ```bash -# SLA offers where the host claims at least 99% reliability +# SLA offers where the host reliability commitments at least 99% reliability vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' # Compare total cost including SLA charge @@ -143,7 +143,7 @@ When you set `target_reliability`, search results include: | --- | --- | | `search.slaPremiumPerHour` | SLA charge for this offer at your target (API field name) | | `dph_total` | Total hourly cost **including** the SLA charge | -| `expected_reliability` | Host's reliability claim | +| `expected_reliability` | Host's reliability commitment | Hover over the price breakdown on an offer card to see GPU, storage, bandwidth, and the SLA charge separately. @@ -153,7 +153,7 @@ When you search with an SLA target, reserved-instance discounts may not apply to ### Comparing offers -| Offer | GPU/hr | Host claim | Your target | SLA charge/hr | +| Offer | GPU/hr | Host commitment | Your target | SLA charge/hr | | --- | --- | --- | --- | --- | | A | $3.50 | 99% | 95% | ~$0.008 | | B | $3.50 | 95% | 95% | much higher | @@ -162,17 +162,17 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d ### API automation -**Prerequisites:** You should be comfortable with REST, an API key, and JSON. Otherwise stay on [In the web console](#in-the-web-console). Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm coverage on the instance. +**Prerequisites:** You should be comfortable with REST, an API key, and JSON. Otherwise stay on [In the web console](#in-the-web-console). Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. Console-only renters can skip the rest of this section. -CLI and SDK `create instance` cannot set `target_reliability`. After a CLI/SDK search, complete the rental in the console (set Reliability target, then confirm an SLA charge line) or use the REST example below. If the instance has no SLA charge line, you do not have coverage. +CLI and SDK `create instance` cannot set `target_reliability`. After a CLI/SDK search, complete the rental in the console (set Reliability target, then confirm an SLA charge line) or use the REST example below. If the instance has no SLA charge line, you do not have an SLA. For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Renters set **`target_reliability`** on search and on REST rent. **`sla_r_target`** is a stored field name in some instance filters — do not send it in the rent body. -**Billing reconciliation:** SLA settlement credits appear in the console billing UI today. They are not included in `GET /api/v0/charges/` and client webhooks for SLA credits are not available — plan manual console reconciliation after UTC settlement (see [FAQ](#where-do-i-see-historical-sla-credits)). +**Billing reconciliation:** service credits appear in the console billing UI today. They are not included in `GET /api/v0/charges/` and client webhooks for SLA credits are not available — plan manual console reconciliation after UTC settlement (see [FAQ](#where-do-i-see-historical-sla-credits)). **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable): @@ -227,12 +227,12 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ **3. Verify** via `GET /api/v1/instances/` or `vastai show instances-v1 --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. Pass an explicit `limit` (default can be as low as **5**; maximum **25** per request). Paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. On the CLI, use `--limit` and `--next-token` with `show instances-v1`. -**Billing reconciliation (console):** confirming coverage does not show SLA settlement credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. +**Billing reconciliation (console):** confirming the SLA does not show service credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. | Symptom | Typical response | What to do | | --- | --- | --- | | Target on a non-SLA offer | HTTP 400 `invalid_args` | Search with `has_sla=true`; confirm `expected_reliability` | -| Target out of range / invalid | HTTP 400 `invalid_args` | Use `0 < target_reliability < 1`; stay at or below a realistic host claim | +| Target out of range / invalid | HTTP 400 `invalid_args` | Use `0 < target_reliability < 1`; stay at or below a realistic host reliability commitment | | Offer unavailable / stale | HTTP 404 `invalid_args` (check `msg` for `no_such_ask`) | Re-search and rent a current offer ID | | Cannot start immediately (`cancel_unavail`) | HTTP 410 `no_such_ask` | Offer cannot start now; pick another offer or retry later — see [Create Instance](/api-reference/instances/create-instance) | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | @@ -249,10 +249,10 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target, the host's claim, and host confidence (how the host priced SLA around their claim) are fixed for that rental. When comparing offers, use the SLA charge line or `dph_total`. Host confidence is not shown in the client UI and is not a setting you control. +1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA charge line or `dph_total`. Host confidence is not shown in the client UI and is not a setting you control. 2. **Daily billing** — you pay compute plus the SLA charge each day. 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. -4. **Credits appear in billing** — settlement credits improve your balance; strong days mean you paid the SLA charge with no credit. +4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA charge with no credit. ### What you pay during an outage @@ -262,7 +262,7 @@ Billing continues during downtime. You are still charged for **compute, storage, **Stop vs destroy:** Stopping pauses compute but storage and contract charges can continue. **Destroying the instance** ends future daily charges; final SLA settlement still posts when the contract closes. If you abandon a failed host, destroy only after saving any data you need. -If you qualify for compensation, a **settlement credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. +If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. ### How reliability is measured @@ -276,15 +276,15 @@ Scheduled maintenance with adequate advance notice (typically 24+ hours) may be ### Credit scenarios (simplified) -Using the H100 example ($84/day compute, ~$0.20/day SLA charge, target 95%, host claim 99%): +Using the H100 example ($84/day compute, ~$0.20/day SLA charge, target 95%, host reliability commitment 99%): -| Scenario | Approx. SLA charge | Approx. settlement credit | Net vs no SLA (approx.) | +| Scenario | Approx. SLA charge | Approx. service credit | Net vs no SLA (approx.) | | --- | --- | --- | --- | | Above target (excellent / good day) | ~$0.20/day | $0 (often) | **−$0.20** (you paid the SLA charge) | | Near / below target on blended measure (~95%) | ~$0.20/day | ~$42 | **+$41.80** (net credit after SLA charge) | | Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | -**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without SLA coverage. +**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without the SLA. Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. @@ -311,7 +311,7 @@ Production settlement uses the multi-window reliability blend described above, n 1. Open **Instances** and select your running instance. 2. Open **price details** (or the instance billing panel) and confirm an **SLA charge** line is present. -3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. If you do not see a target or SLA charge, you likely rented without SLA coverage. +3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. If you do not see a target or SLA charge, you likely rented without the SLA. ### API integrators @@ -322,21 +322,21 @@ Console users: open **Instances** → select your instance → **price details** Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). -To find SLA-covered instances, filter **client-side** from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Prefer client-side filtering in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone for SLA detection. +To find instances with an SLA, filter **client-side** from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Prefer client-side filtering in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone to detect an SLA. | Client-visible concept | Search / bundles | Active rental (`GET /api/v1/instances/`) | | --- | --- | --- | | Your reliability target | `target_reliability` (quote only until rent) | `target_reliability` | | SLA charge rate | `search.slaPremiumPerHour` | `instance.slaPremiumPerHour` | -| Host SLA claim | `expected_reliability` | `sla_r_claim` | +| Host reliability commitment | `expected_reliability` | `sla_r_claim` | -Host ask field `sla_r_claim` on listings is host-side; on active rentals the locked claim appears as `sla_r_claim` in show-instances. Host confidence is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers. +Host ask field `sla_r_claim` on listings is host-side; on active rentals the locked reliability commitment appears as `sla_r_claim` in show-instances. Host confidence is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers.
## When SLA is not available - **Interruptible (bid) rentals** never include SLA, even on SLA-enabled machines. Use on-demand with a reliability target set. -- **Prepaid / reserved-only flows** may reject SLA parameters. Use on-demand rentals for SLA coverage. +- **Prepaid / reserved-only flows** may reject SLA parameters. Use on-demand rentals for an SLA. - Offers without SLA (`expected_reliability = 0` / `has_sla=false`) are excluded when you filter with `has_sla=true` or set a positive `target_reliability`. - If SLA parameters on an offer are invalid for your target, search may flag an SLA pricing error instead of showing a charge. @@ -358,7 +358,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta **Console:** After UTC settlement, open **Account → Billing** and look for SLA credit line items alongside compute charges. -**API:** Prefer **Account → Billing** for SLA settlement credit reconciliation. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. +**API:** Prefer **Account → Billing** for service credit reconciliation. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. ## Related documentation diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 8a396124..4f969fcf 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -6,7 +6,7 @@ description: "Set up hosting on Vast.ai: accounts, machines, offers, maintenance -**Looking to rent GPUs?** See [Finding & Renting Instances](/guides/instances/choosing/find-and-rent) and [SLA Coverage](/guides/instances/choosing/sla-coverage). +**Looking to rent GPUs?** See [Finding & Renting Instances](/guides/instances/choosing/find-and-rent) and [SLA](/guides/instances/choosing/sla-coverage). Vast is a GPU marketplace. Hosts sell GPU resources on the marketplace. Hosts are responsible for: @@ -40,7 +40,7 @@ Clients have high expectations coming from AWS or GCP. As a host, plan to offer ## Offers and Rental Contracts -Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). SLA claim and confidence require **Set Pricing → SLA** in the console or REST `create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). +Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or REST `create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). The main offer parameters include: @@ -49,7 +49,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (uptime guarantee):** Optional add-on for on-demand listings. In short: you state a reliability **claim**, the renter picks a **target**, they pay a small extra hourly fee, and if uptime misses that target they get a credit from your earnings. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language), then the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. Renters: [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). +- **SLA (uptime guarantee):** Optional add-on for on-demand listings. In short: you state a reliability **commitment**, the renter picks a **target**, they pay a small extra hourly fee, and if uptime misses that target they get a credit from your earnings. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language), then the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. Renters: [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. @@ -236,7 +236,7 @@ CLI self-tests create **non-SLA** rentals (`vastai create instance` does not acc 2. In the console Search filters, set a **Reliability target**, rent your own offer, and confirm an **SLA charge** line before continuing — or `PUT /api/v0/asks/{id}/` with `target_reliability`. 3. Destroy the test instance when done. -See [SLA Coverage](/guides/instances/choosing/sla-coverage) for renter-side details. +See [SLA](/guides/instances/choosing/sla-coverage) for renter-side details. You can then look at your [instance tab](https://cloud.vast.ai/instances/) to make sure that pytorch loaded correctly along with jupyter and ssh. Click on the \<\_ button to get the ssh command to connect to the instance. Test the direct ssh command. Click on the open button to test jupyter. If the button is stuck "connecting" then there is most likely a problem with the port configuration on the router in front of the machine. Once finished, destroy the instance. @@ -253,7 +253,7 @@ Use these paths in order: 1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. 2. **Planned SLA maintenance (active renters):** If SLA is enabled, use [`vastai schedule maint`](/host/cli/schedule-maint) with a start time at least 24 hours in the future. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance) for credit eligibility. -3. **Emergency or unplanned downtime:** Use [`vastai schedule maint`](/host/cli/schedule-maint) immediately to notify renters. Full SLA settlement exposure may apply. +3. **Emergency or unplanned downtime:** Use [`vastai schedule maint`](/host/cli/schedule-maint) immediately to notify renters. The full service-credit amount that can be owed may apply. The same `schedule maint` command supports planned and emergency notifications; advance notice and duration determine SLA credit eligibility. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 3e2fb975..26c7d404 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -8,7 +8,7 @@ The **SLA (Service Level Agreement) earnings backtester** lets you answer a prac **Console hosts:** use **Set Pricing → SLA** in the web console to preview SLA charges — you do not need this API. -**API hosts:** this endpoint replays historical earnings through SLA math to estimate SLA charges and worst-day credit risk before listing. (**`r`** = reliability level used as both claim and target in the simulation; **`p`** = host confidence — both defined in [Query parameters](#query-parameters) below.) +**API hosts:** this endpoint replays historical earnings through SLA math to estimate SLA charges and worst-day credit risk before listing. (**`r`** = reliability level used as both reliability commitment and target in the simulation; **`p`** = host confidence — both defined in [Query parameters](#query-parameters) below.) It replays your machine's **real historical compute earnings and reliability** through the same SLA settlement math used in production, then compares the simulated result to what you actually earned from SLA (if anything). @@ -34,7 +34,7 @@ If `has_data` is `false`, widen the date range or pick a machine with more renta Use the backtester to: -- Pick a reliability claim and confidence before you enable SLA on a listing +- Pick a reliability commitment and confidence before you enable SLA on a listing - Compare how SLA charge and worst-case credit change across targets - Stress-test a lower reliability assumption before you commit - Compare to history — each day includes `historical_sla`, your machine's realized SLA earnings on that day (zero if you were not offering SLA) @@ -48,13 +48,13 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 3. For each active day, it computes GPU, storage, and bandwidth earnings plus simulated SLA host earnings. 4. It returns a day-by-day breakdown and summary totals. -**Simulated vs listing parameters.** In the backtester, reliability **claim and client target are both set to `r`**. That is a conservative what-if: it pretends every client targeted your claim. When you list, you set only **`sla_r_claim`** (and `sla_sigma_x`); clients choose their own `target_reliability` at search/rent time. Workflow: backtest `worst_day_loss` at a candidate claim level, then verify visible SLA charges in **Set Pricing → SLA** (or `dph_total` in search at realistic client targets) before listing. +**Simulated vs listing parameters.** In the backtester, the reliability **commitment and the client reliability target are both set to `r`**. That is a conservative what-if: it pretends every client targeted your reliability commitment. When you list, you set only **`sla_r_claim`** (and `sla_sigma_x`); clients choose their own `target_reliability` at search/rent time. Workflow: backtest `worst_day_loss` at a candidate reliability commitment, then verify visible SLA fees in **Set Pricing → SLA** (or `dph_total` in search at realistic client targets) before listing. **Active vs idle days.** **Idle days** are days with no rental earnings on the machine (no active compute rental). These days typically produce no SLA charge or credit in the simulation. Days with no rental activity appear in the results as zero-filled rows but do not count toward `covered_days`. Only days with actual earnings are replayed through SLA math. **Simulation vs live listing** -- The backtester sets claim equal to target and may show higher SLA charges than live listing when clients choose targets below your claim. +- The backtester sets the reliability commitment equal to target and may show higher SLA charges than live listing when clients choose targets below your reliability commitment. - For client-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or search with a realistic `target_reliability`. - For tail risk, trust `worst_day_loss`, not headline `total_sla`. - Timescale mix (`β`) is derived from `r` (weights recent vs longer-term uptime in settlement). Hosts cannot set β via the listing API. @@ -86,7 +86,7 @@ Requires Bearer authentication. This endpoint is rate-limited like other host AP | Parameter | Required | Description | | --- | --- | --- | | `machine_id` | Yes | ID of your machine | -| `r` | Yes | Reliability level to simulate (greater than 0 and at most **0.9999**). Used as **both claim and client target** in the simulation. Example: `0.95` = 95%. Exactly `1.0` is rejected. | +| `r` | Yes | Reliability level to simulate (greater than 0 and at most **0.9999**). Used as **both reliability commitment and client target** in the simulation. Example: `0.95` = 95%. Exactly `1.0` is rejected. | | `p` | No | Host confidence (greater than 0 and **less than 1** — not equal to 1). Maps to the same spread used when listing with `sla_sigma_x` — see [Confidence values](#confidence-values-p) below. Default: `0.6667` (normal confidence, ≈ 67%). | | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | @@ -230,7 +230,7 @@ Your historical reliability was strong relative to the simulated target. SLA wou ### Negative `sla` on specific days -Those days had reliability below the simulated target. The magnitude shows how much you would have credited. If you see clusters of negative days, consider a lower claim, wider confidence, or fixing reliability before listing SLA. +Those days had reliability below the simulated target. The magnitude shows how much you would have credited. If you see clusters of negative days, consider a lower reliability commitment, wider confidence, or fixing reliability before listing SLA. ### `total_sla` near zero @@ -238,11 +238,11 @@ Break-even territory — SLA charges and credits roughly balance. Typical when y ### `total_sla` strongly negative -Under the simulated parameters, SLA would have cost you money over this window. Either improve reliability, lower the claim, or widen confidence before listing. +Under the simulated parameters, SLA would have cost you money over this window. Either improve reliability, lower the reliability commitment, or widen confidence before listing. ### Using `reliability` override -Setting `reliability=0.90` while keeping `r=0.99` answers: *if every active day had 90% uptime, how bad would SLA credits get?* Use this to understand worst-case credit exposure before committing to a high claim. +Setting `reliability=0.90` while keeping `r=0.99` answers: *if every active day had 90% uptime, how bad would SLA credits get?* Use this to understand worst-case credit exposure before committing to a high reliability commitment. ## Confidence values (`p`) @@ -267,7 +267,7 @@ Tighter confidence (higher `p`) does **not** reduce credit owed on a miss — us | 400 | `invalid_range` | Date window invalid | | 400 | `range_too_large` | Window exceeds the maximum span | | 400 | `bad_request` | Out-of-range `r`, `p`, or date parameters | -| 400 | `invalid_params` | Simulation math failure after validation (check claim/confidence inputs) | +| 400 | `invalid_params` | Simulation math failure after validation (check the reliability commitment/confidence inputs) | | 403 | `not_owner` | Machine belongs to another host | | 404 | `machine_not_found` | Invalid `machine_id` | | 429 | *(rate limited)* | Too many requests — retry with backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | @@ -278,13 +278,13 @@ For missing or invalid API keys and permission denials (`machine_read`), see [Au 1. **Run a baseline backtest** on a machine with at least a few weeks of rental history: - Check your machine's uptime history on the [Host Machines page](https://cloud.vast.ai/host/machines), then use the console SLA preview or backtester — do not rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). - - Choose an `r` at or slightly below the claim you plan to publish. + - Choose an `r` at or slightly below the reliability commitment you plan to publish. - Use normal confidence (`p=0.6667`). - If `has_data` is `false`, widen the date range or wait for more rental history. 2. **Check `worst_day_loss`** — can you absorb that credit from a bad day? 3. **Try a higher `r`** (for example `0.99`) and see how `total_sla` changes. -4. **Run a stress test** with `reliability=0.90` at your intended claim. -5. **List with `sla_r_claim`** — set claim (and `sla_sigma_x`) on the offer; clients choose their own targets in search (see [SLA Offers](/host/sla-offers)). +4. **Run a stress test** with `reliability=0.90` at your intended reliability commitment. +5. **List with `sla_r_claim`** — set the reliability commitment (and `sla_sigma_x`) on the offer; clients choose their own targets in search (see [SLA Offers](/host/sla-offers)). ## Fleet workflow @@ -326,5 +326,5 @@ Expect roughly two seconds per machine minimum (`sleep 2` plus request time). Fo - [SLA Backtest API](/api-reference/host/sla-backtest) — formal API reference for this endpoint - [SLA Offers](/host/sla-offers) — listing parameters, economics, and risk scenarios -- [SLA Coverage (clients)](/guides/instances/choosing/sla-coverage) — how renters choose targets and read `dph_total` +- [SLA (clients)](/guides/instances/choosing/sla-coverage) — how renters choose targets and read `dph_total` - [API permissions](/api-reference/permissions) — `machine_read` scope required diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1a377eed..f724c47e 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -1,19 +1,19 @@ --- title: "SLA Offers" -description: "Offer reliability guarantees on your machines, set claim and confidence, and understand how SLA charges and payouts work." +description: "Offer an SLA on your machines: set a reliability commitment and confidence, and see how the SLA fee and service credits work." "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose coverage pay a small hourly **SLA charge** included in **`dph_total`** (dollars per hour total in search — base compute plus SLA charge), and if measured reliability falls short of their chosen target, they receive a settlement credit funded from your earnings. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose an SLA pay a small hourly **SLA charge** included in **`dph_total`** (dollars per hour total in search — base compute plus SLA charge), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. -This page explains how SLA offers work from the host side — what you set, how clients choose coverage, and what happens when uptime is good or bad. +This page explains how SLA offers work from the host side — what you set, how clients choose an SLA, and what happens when uptime is good or bad. SLA settlement is **asymmetric by design**: when reliability is strong relative to the client's target, you keep the SLA charge; when it falls short, client credits can exceed the charge you collected that day. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). -**Clients:** see [SLA Coverage](/guides/instances/choosing/sla-coverage) for how SLA appears in search and billing. +**Clients:** see [SLA](/guides/instances/choosing/sla-coverage) for how SLA appears in search and billing. ## Choose your path @@ -32,7 +32,7 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative 2. Test on a [separate client account](/host/hosting-overview#testing-your-own-machine) (billed like any rental). 3. Install the [CLI](/cli/hello-world) (required for SLA maintenance scheduling). 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). -5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set claim/confidence. +5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. 6. Enable SLA listing and verify in search (`machine_id=` filter). 7. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental. @@ -42,7 +42,7 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative If you expect downtime during active rentals, install the [Vast CLI](/cli/hello-world) (or plan to use the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)) **before** enabling SLA. Planned SLA maintenance must be scheduled at least 24 hours ahead via CLI or REST — there is no in-console maintenance scheduler today.
-**Pre-flight checklist (before tuning claim/confidence):** +**Pre-flight checklist (before tuning reliability commitment and confidence):** - Hosting requires a separate host account and hosting agreement — see [Account setup](/host/hosting-overview#account-setup-and-hosting-agreement) if you have not completed host onboarding. - Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai) to request access before configuring a fleet. Approval timing varies; complete host setup and a base listing first. @@ -55,27 +55,27 @@ Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machin Before enabling SLA, finish normal listing setup: test your machine, set GPU price and offer end date, choose on-demand vs interruptible, and understand [Testing your own machine](/host/hosting-overview#testing-your-own-machine) and offer terms in [Hosting overview](/host/hosting-overview). -On outage days you may still bill clients for **intended** compute **and** owe SLA settlement credits. Tail-risk exposure can approach a full day’s compute per affected contract — not just the daily SLA charge shown in previews. Read [Billing vs settlement](#billing-vs-settlement-important) before enabling SLA. +On outage days you may still bill clients for **intended** compute **and** owe service credits. Tail-risk exposure can approach a full day’s compute per affected contract — not just the daily SLA charge shown in previews. Read [Billing vs settlement](#billing-vs-settlement-important) before enabling SLA. -**Rental types:** SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible instances on an SLA-enabled machine are not SLA-covered; on-demand contracts on the same machine are. Reserved or prepay attempts on an SLA-enabled offer are not supported — use on-demand to rent with SLA. +**Rental types:** The SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible instances on a machine with an SLA are not on the SLA; on-demand contracts on the same machine are. Reserved or prepay attempts on an offer with an SLA are not supported — use on-demand to rent with an SLA. - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. -- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting `worst_day_loss`. Consider wider confidence or a more conservative claim until you have a few weeks of data. +- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting `worst_day_loss`. Consider wider confidence or a more conservative reliability commitment until you have a few weeks of data. ## SLA in plain language SLA is an optional reliability promise on **on-demand** rentals. You do not have to offer it. -1. **You (the host)** say how often you expect the machine to be up. That is your **claim**. -2. You also say how sure you are of that claim. That is your **confidence**. Tighter confidence makes the renter's extra fee smaller. -3. The **renter** picks how much uptime they want. That is their **target**. You do not set their target. -4. The renter pays a small extra hourly fee, the **SLA charge**, on top of the GPU price. +1. **You (the host)** state a **reliability commitment**: how often you expect the machine to be up. The API field is `sla_r_claim`. The console may still label this **Claim**. +2. You also set **confidence**: how sure you are of that commitment. This is a spread, not odds. Tighter confidence makes the renter's SLA fee smaller. +3. The **renter** picks a **reliability target**. You do not set their target. +4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. If uptime met their target, you keep the fee. -7. If uptime missed their target, the renter gets a **credit** from your earnings. One bad day can cost more than many days of fees. +6. If uptime met their reliability target, you keep the SLA fee. +7. If uptime missed their reliability target, the renter receives a **service credit** from your earnings. One bad day can cost more than many days of fees. What this is not: @@ -84,24 +84,24 @@ What this is not: - It applies only to **on-demand** rentals, not interruptible or reserved ones. - An outage does not erase that day's GPU bill. The renter's compensation is a separate credit. -The field names for claim, confidence, and target are in [How it works (plain English)](#how-it-works-plain-english) below. Renters get the same story in [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). +The field names for the reliability commitment (`sla_r_claim`), confidence, and reliability target are in [How it works (plain English)](#how-it-works-plain-english) below. Renters get the same story in [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). ## How it works (plain English) In **Host → Machines → Set Pricing → SLA** you set host knobs only: -- **Claim** — the reliability level you believe your machine will deliver (shown to clients as `expected_reliability`). -- **Confidence** — how tightly you price around that claim (`sla_sigma_x`; lower = tighter / cheaper for clients at a given target). +- **Reliability commitment** — how often you expect the machine to be up (shown to clients as `expected_reliability`; API field `sla_r_claim`; the console may still label this Claim). +- **Confidence** — how tightly you price around that commitment (`sla_sigma_x`; lower = tighter / cheaper for clients at a given reliability target). This is not odds. Clients choose their own **reliability target** at search and rent time. You do **not** set the client target on the listing. Think of an SLA offer as two host ideas plus one client choice: -1. **Your reliability claim** — what you believe your machine will deliver (`sla_r_claim`). Setting this above `0` enables SLA on the offer. -2. **Your confidence** — how wide your belief is around that claim (`sla_sigma_x`). Tighter confidence → lower SLA charges for clients at a given target; wider confidence → higher charges. -3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA charge sizing use this target. Clients typically pick a target **at or below** your claim. +1. **Your reliability commitment** — what you believe your machine will deliver (`sla_r_claim`). Setting this above `0` enables SLA on the offer. +2. **Your confidence** — how wide your belief is around that reliability commitment (`sla_sigma_x`). Tighter confidence → lower SLA charges for clients at a given target; wider confidence → higher charges. +3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA charge sizing use this target. Clients typically pick a target **at or below** your reliability commitment. When a client rents an on-demand instance on your SLA-listed offer with a chosen target: @@ -125,7 +125,7 @@ On sliced machines, SLA settles **per rental contract**. If one GPU slice fails ### Billing vs settlement (important) -For SLA-covered on-demand contracts, compute billing uses the **intended daily compute** for the rental. Offline time is tracked as an outage in reliability observations. Client compensation for poor reliability flows through **SLA settlement credits**, not by silently zeroing the day's compute bill. +For SLA-covered on-demand contracts, compute billing uses the **intended daily compute** for the rental. Offline time is tracked as an outage in reliability observations. Client compensation for poor reliability flows through **service credits**, not by silently zeroing the day's compute bill. ## SLA parameters @@ -133,28 +133,28 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | -| Reliability claim | `sla_r_claim` | `r` (backtester sets claim = target = `r`) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | -| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the claim. Lower = more confident (lower SLA charges for clients at a given target). Defaults to `0.5` if omitted. | +| Reliability commitment | `sla_r_claim` | `r` (backtester sets the reliability commitment = target = `r`) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | +| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA charges for clients at a given target). Defaults to `0.5` if omitted. | ### Advanced: `sla_max_beta` (optional) **Support-only — omit unless Vast support directs you.** Hosts do **not** set β (timescale mix). The platform derives β from the client's `target_reliability` at rent time. -`sla_max_beta` is an optional ask term that caps how aggressively long-running contracts may weigh recent uptime versus longer history in settlement. Leave it unset for an uncapped offer. If you set it, it must be in `(0, 1)` and at least the default β derived at your claim — otherwise listing is rejected. +`sla_max_beta` is an optional ask term that caps how aggressively long-running contracts may weigh recent uptime versus longer history in settlement. Leave it unset for an uncapped offer. If you set it, it must be in `(0, 1)` and at least the default β derived at your reliability commitment — otherwise listing is rejected. -**`sla_r_target` is not host-settable.** If you send `sla_r_target` or legacy `sla_reliability` on `create_asks/`, they are **ignored**. Clients supply their coverage target at search/rent time (`target_reliability`). Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x` — they use different scales. Use the mapping table on the [backtester page](/host/sla-backtester#confidence-values-p). +**`sla_r_target` is not host-settable.** If you send `sla_r_target` or legacy `sla_reliability` on `create_asks/`, they are **ignored**. Clients supply their reliability target at search/rent time (`target_reliability`). Do **not** copy numeric `p` values from the SLA Backtester into `sla_sigma_x` — they use different scales. Use the mapping table on the [backtester page](/host/sla-backtester#confidence-values-p). | Concept | Console | Listing API | Backtester | Client sees / sets | | --- | --- | --- | --- | --- | -| Reliability claim | Claim | `sla_r_claim` | `r` (claim = target in sim) | `expected_reliability` | +| Reliability commitment | Claim | `sla_r_claim` | `r` (claim = target in sim) | `expected_reliability` | | Confidence | Confidence / spread | `sla_sigma_x` | `p` (different scale) | — | | Reliability target | — (client-chosen) | — (not on asks) | `r` (same as claim in sim) | `target_reliability` in search | | All-in hourly price | — | — | — | `dph_total` (compute plus SLA charge when enabled) | -**Confidence is not an uptime target.** It controls how aggressively SLA charges are priced around your claim. +**Confidence is not an uptime target.** It controls how aggressively SLA charges are priced around your reliability commitment. ### Machine reliability score vs SLA reliability @@ -163,9 +163,9 @@ The **reliability score** on the Host Machines page reflects connection and inst Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r_claim`: -1. Open **Host → Machines** → **Set Pricing → SLA** and review the console SLA charge preview at candidate claims. +1. Open **Host → Machines** → **Set Pricing → SLA** and review the console SLA charge preview at candidate reliability commitments. 2. If you have rental history, run the [backtester](/host/sla-backtester) and check top-level `reliability` in the response. -3. Set **claim** at a level you can sustain; clients who pick targets below your claim see lower SLA charges. +3. Set **reliability commitment** at a level you can sustain; clients who pick targets below your reliability commitment see lower SLA charges. ### Confidence values @@ -186,8 +186,8 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.9999**. Exactly `1.0` is rejected. -- When claim is positive, `sla_sigma_x` must be positive and at most `3.0` (defaults to `0.5` if omitted). -- Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your claim. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. +- When the reliability commitment is positive, `sla_sigma_x` must be positive and at most `3.0` (defaults to `0.5` if omitted). +- Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. If listing is rejected with `error: "invalid_sla_params"`, check the `msg` field against the rules above. Other SLA listing errors include `sla_not_approved` and `sla_daemon_outdated`. @@ -226,7 +226,7 @@ If the machine is already **listed**: 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. 3. Verify after listing: - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. - - **Search:** `dph_total` includes the SLA charge at a client's `target_reliability`, and `expected_reliability` matches your claim (see [Search / client-visible fields](#search--client-visible-fields)). + - **Search:** `dph_total` includes the SLA charge at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same as pressing **LIST** or running `vastai list machine`), not a save-only draft. @@ -234,7 +234,7 @@ In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIS #### Web console SLA preview -In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA charge and payout exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA charge and service-credit exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. ### API (for automation) @@ -271,7 +271,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ Replace `end_date` with a **future** Unix timestamp — past dates expire the offer immediately (example `1893456000` = 2030-01-01 00:00 UTC). Set `end_date` so the offer does not stay open indefinitely — especially important for SLA commitments. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`. -Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric payout risk. See [Offer End Date](/host/hosting-overview#offer-end-date). +Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). Do not use the JSON below alone for a **first** listing. First-time `create_asks` requests must also include `min_chunk` and typical disk/bandwidth pricing — see [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). Use this as an **SLA-fields** reference when base pricing is already configured. @@ -289,7 +289,7 @@ SLA fields example (existing listing): } ``` -This creates an offer with claim `0.99` and confidence spread `0.5`. Clients who search with `target_reliability` below your claim see lower SLA charges than clients who ask for coverage near your claim. +This creates an offer with a reliability commitment of `0.99` and confidence spread `0.5`. Clients who search with `target_reliability` below your reliability commitment see a lower SLA fee than clients who choose a reliability target near your reliability commitment. Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_claim` to `0` to disable SLA on an existing listing. @@ -307,7 +307,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge ### Fleet listing workflow (advanced — fleet operators only) -`PUT /api/v0/machines/create_asks/` publishes a live listing (same as **LIST**). Only run this loop on machines you intend to list or update. Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding claim/confidence. Skip incomplete machines. +`PUT /api/v0/machines/create_asks/` publishes a live listing (same as **LIST**). Only run this loop on machines you intend to list or update. Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. **Before fleet SLA rollout:** @@ -318,7 +318,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge For multiple machines, loop sequentially — do not parallelize without backoff: 1. Skip machines missing base pricing fields. -2. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields (preserve existing claim/confidence when set). +2. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields (preserve existing reliability commitment and confidence when set). 3. On `429`, sleep and retry with exponential backoff. 4. On `invalid_sla_params`, `sla_not_approved`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. @@ -338,7 +338,7 @@ for id in $(vastai show machines -q); do if [ -z "$price" ] || [ -z "$end" ] || [ -z "$chunk" ]; then echo "skip $id: missing price_gpu/end_date/min_chunk"; continue fi - # Opt-in only: skip machines with no positive SLA claim (do not invent 0.99) + # Opt-in only: skip machines with no positive reliability commitment (do not invent 0.99) if ! echo "$machine" | jq -e '(.sla_r_claim // 0) > 0' >/dev/null; then echo "skip $id: no positive sla_r_claim (enable SLA per machine first)"; continue fi @@ -357,7 +357,7 @@ for id in $(vastai show machines -q); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure claim/confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. **SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: @@ -407,7 +407,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ ## Economics walkthrough -**Setup:** You list an H100 at **$3.50/hr** GPU price with claim **99%** and normal confidence (`sla_sigma_x = 0.5`). A client searches with **target 95%**. +**Setup:** You list an H100 at **$3.50/hr** GPU price with reliability commitment **99%** and normal confidence (`sla_sigma_x = 0.5`). A client searches with **target 95%**. | Item | Amount | | --- | --- | @@ -416,10 +416,10 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ SLA credits are capped relative to that UTC day's covered compute — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat `worst_day_loss` from the [SLA backtester](/host/sla-backtester) as the authoritative tail-risk figure before you list. -SLA charge sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst single-day credit exposure (`worst_day_loss`), not exact client SLA charges. For authoritative client-visible charges, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers at a chosen `target_reliability` — not backtester `total_sla` when clients will rent below your claim. +SLA charge sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst single-day credit exposure (`worst_day_loss`), not exact client SLA charges. For authoritative client-visible charges, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers at a chosen `target_reliability` — not backtester `total_sla` when clients will rent below your reliability commitment. -The backtester sets claim equal to target (`r`), which is a **conservative** what-if (as if every client targeted your claim). Live clients who choose targets **below** your claim usually see lower SLA charges than the backtester's simulated charges. Use `worst_day_loss` from the backtester as your worst single-day credit reference, then verify visible charges in **Set Pricing → SLA** (or `dph_total` in search) before listing. +The backtester sets the reliability commitment equal to target (`r`), which is a **conservative** what-if (as if every client targeted your reliability commitment). Live clients who choose targets **below** your reliability commitment usually see lower SLA charges than the backtester's simulated charges. Use `worst_day_loss` from the backtester as your worst single-day credit reference, then verify visible charges in **Set Pricing → SLA** (or `dph_total` in search) before listing. ### Search / client-visible fields @@ -427,10 +427,10 @@ The backtester sets claim equal to target (`r`), which is a **conservative** wha When SLA is enabled on an offer, clients see: - **`dph_total`** — total $/hour including the SLA charge at their `target_reliability` (authoritative for client-visible all-in pricing). -- **`expected_reliability`** — your advertised claim (maps to `sla_r_claim`). -- **`reliability` / `reliability2`** — historical machine reliability scores, **not** your SLA claim. +- **`expected_reliability`** — your advertised reliability commitment (maps to `sla_r_claim`). +- **`reliability` / `reliability2`** — historical machine reliability scores, **not** your reliability commitment. -**Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the SLA claim. The published SLA claim appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, use `has_sla=true` or filter on `expected_reliability > 0`; do not use the `reliability` filter as an SLA selector. +**Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the reliability commitment. The published reliability commitment appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, use `has_sla=true` or filter on `expected_reliability > 0`; do not use the `reliability` filter as an SLA selector. Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand): @@ -450,15 +450,15 @@ In the **You net** column, values follow host earnings sign conventions: positiv You keep most or all of the SLA charge. -### What if measured reliability is between the client's target and my claim? +### What if measured reliability is between the client's target and my reliability commitment? -Example: you publish **claim 99%**, the client chose **target 95%**, and measured reliability is **~97%**. +Example: you publish **reliability commitment 99%**, the client chose **target 95%**, and measured reliability is **~97%**. -- **Credits** are evaluated against the client's **target** (95%), not your claim. +- **Credits** are evaluated against the client's **target** (95%), not your reliability commitment. - Because 97% is above 95%, you typically **owe no SLA credit** for that day. -- **SLA charges** are priced from your **claim**, confidence, and the client's target — a higher claim relative to the target generally means lower client charges. +- **SLA charges** are priced from your **reliability commitment**, confidence, and the client's target — a higher reliability commitment relative to the target generally means lower client charges. -**Claim** is your belief/pricing knob; the client's **target** is what drives payout eligibility. +The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what drives service-credit eligibility. ### If the client's target is missed @@ -479,17 +479,17 @@ Your maximum SLA loss on any single settlement day is bounded by that day's cove ## Risk scenarios -### You claim 99% and deliver 99.5% +### Reliability commitment 99%, delivered 99.5% -You outperform your claim. Clients who chose targets at or below 99% pay small SLA charges; credits are rare. You net positive on SLA over time. +You outperform your reliability commitment. Clients who chose targets at or below 99% pay small SLA charges; credits are rare. You net positive on SLA over time. -### You claim 99% but have an offline day +### Reliability commitment 99% with an offline day Clients receive credits tied to how far measured reliability falls below **their** target. Extended outages can approach a full-day compute credit. Your reliability score and verification status may also be affected separately from SLA settlement. -### Clients target near your claim +### Clients target near your reliability commitment -SLA charges are **much higher** when the client's target sits near your claim (little headroom). Prefer a claim you can sustain above the targets clients actually choose. +SLA charges are **much higher** when the client's target sits near your reliability commitment (little headroom). Prefer a reliability commitment you can sustain above the targets clients actually choose. ### You widen confidence (`sla_sigma_x` → 1.0) @@ -528,11 +528,11 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m ## When things go wrong -- **Listing rejected (`invalid_sla_params`)** — Re-check claim and `sla_sigma_x` against [validation rules](#validation-rules). +- **Listing rejected (`invalid_sla_params`)** — Re-check the reliability commitment and `sla_sigma_x` against [validation rules](#validation-rules). - **`sla_not_approved`** — Contact support; you can keep a non-SLA listing while approval is pending. - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — Review reliability; re-run the backtester with a low `reliability` stress value (for example `0.01`). -- **Severe outage** — Disable SLA on new contracts: open **Host → Machines** → **Set Pricing → SLA**, set claim to `0` (or use API `sla_r_claim=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. +- **Severe outage** — Disable SLA on new contracts: open **Host → Machines** → **Set Pricing → SLA**, set the reliability commitment to `0` (or use API `sla_r_claim=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. ## Monitoring SLA after listing @@ -581,7 +581,7 @@ Positive `sla_earn` = net SLA charge you kept that period; negative = net credit ### API (automation) -**Console users:** Skip this section if you check payouts in **Host → Billing**. No API key is required. +**Console users:** Skip this section if you check billing in **Host → Billing**. No API key is required. **API keys for SLA** @@ -632,15 +632,15 @@ Do **not** compare `last_days=7` totals to single-day `worst_day_loss` from the ## Tips for competitive SLA offers -- **Claim a level you can sustain.** Clients who choose targets below your claim see lower SLA charges and still get meaningful coverage. +- **Commit to a level you can sustain.** Clients who choose reliability targets below your reliability commitment see a lower SLA fee and still get a meaningful SLA. - **Tighten confidence only when earned.** Use a tighter spread (`sla_sigma_x ≈ 0.2`) after you have a strong reliability track record on that machine. - **Keep the machine online during active contracts.** SLA credits and verification are separate systems, but both respond to downtime. - **SLA applies to on-demand rentals only.** It does not apply to interruptible/bid instances or reserved/prepay rentals. When a client starts an on-demand rental on an SLA-enabled offer, SLA terms lock for that rental contract and do not change if you later edit the offer. -- **Use the [SLA backtester](/host/sla-backtester) (API-only)** to preview how different claims and confidence levels would have affected past earnings. +- **Use the [SLA backtester](/host/sla-backtester) (API-only)** to preview how different reliability commitments and confidence levels would have affected past earnings. ## Related documentation -- [SLA Coverage (clients)](/guides/instances/choosing/sla-coverage) — how renters find and evaluate SLA offers +- [SLA (clients)](/guides/instances/choosing/sla-coverage) — how renters find and evaluate SLA offers - [SLA Earnings Backtester](/host/sla-backtester) — preview SLA economics on historical earnings - [Hosting Overview](/host/hosting-overview) — offers, rental contracts, and listing basics - [Understanding Verification](/host/understanding-verification) — platform verification (separate from SLA, but related to trust) diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index cf0ad0da..60d86648 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create_instance" Create a new instance from an offer/ask ID returned by search. -**SLA coverage:** `target_reliability` is not available on `create_instance()` today. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable SLA — see [SLA Coverage](/guides/instances/choosing/sla-coverage#api-automation). +**SLA:** `target_reliability` is not available on `create_instance()` today. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). ## Signature @@ -165,7 +165,7 @@ VastAI.create_instance( ## Returns -`dict`. On success, the response includes `new_contract` — the rental contract / instance ID to use with destroy and `GET /api/v1/instances/` (`vastai show instances-v1`). The `id` you pass to `create_instance()` is the offer/ask ID from search, not `new_contract`. `create_instance()` cannot set `target_reliability`; use REST for SLA coverage. +`dict`. On success, the response includes `new_contract` — the rental contract / instance ID to use with destroy and `GET /api/v1/instances/` (`vastai show instances-v1`). The `id` you pass to `create_instance()` is the offer/ask ID from search, not `new_contract`. `create_instance()` cannot set `target_reliability`; use REST for an SLA. ## Example @@ -181,7 +181,7 @@ result = client.create_instance( print(result) ``` -**SLA via REST:** `create_instance()` cannot set `target_reliability`. To enable coverage, rent with REST and pass the same target you searched with: +**SLA via REST:** `create_instance()` cannot set `target_reliability`. To enable the SLA, rent with REST and pass the same target you searched with: ```bash curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ @@ -194,4 +194,4 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ }' ``` -See [SLA Coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation). +See [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation). diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index e4dbddc9..7677446c 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -56,7 +56,7 @@ vastai schedule maint MACHINE_ID \ ### Emergency or unplanned maintenance -If the machine must go offline without adequate notice, still run `schedule maint` to notify renters — but expect full SLA settlement exposure when SLA is enabled. Use the current UTC epoch for `--sdate` and an integer `--duration` (hours): +If the machine must go offline without adequate notice, still run `schedule maint` to notify renters — but expect the full service-credit amount that can be owed when SLA is enabled. Use the current UTC epoch for `--sdate` and an integer `--duration` (hours): ```bash vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power From a0ac436bbd7f7d5a0bf175c3b5c1ca77c78977b1 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 08:31:46 -0700 Subject: [PATCH 057/250] docs(sla): address doc-review consensus (cycle 13) Fix the broken search comment, map the console Claim label to reliability commitment, and show a Python REST rent example. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-offers.mdx | 2 +- sdk/python/reference/create-instance.mdx | 22 +++++++++++++++++++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b9642407..e2b7f4fa 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -272,9 +272,9 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user } ``` -This is the minimum for search, REST rent, and verify. Add `user_read` if the flow loads templates or account profile data, and `user_write` if it creates SSH keys or templates. See the instance-management example under [Creating Scoped Keys](#creating-scoped-keys). +This is the minimum for search, REST rent, and verification. Add `user_read` if the flow loads templates or account profile data, and `user_write` if it creates SSH keys or templates. See the instance-management example under [Creating Scoped Keys](#creating-scoped-keys). -**service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. +**Service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. OpenAPI documents charge `type` values only; do not use this endpoint alone to reconcile SLA credits. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 8953c815..d52cbf41 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -130,7 +130,7 @@ CLI and API examples below use the same filters. **CLI examples:** ```bash -# SLA offers where the host reliability commitments at least 99% reliability +# SLA offers where the host's reliability commitment is at least 99% vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' # Compare total cost including SLA charge diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f724c47e..17cdfae9 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -214,7 +214,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. -4. Set **Claim** and **Confidence**. For your first listing, choose **Normal** (`sla_sigma_x ≈ 0.5`) unless your uptime history is volatile — see [Confidence values](#confidence-values) for risk tradeoffs. +4. Set **Claim** and **Confidence**. **Claim** in the console is your reliability commitment (`sla_r_claim`); renters see it as expected reliability on the offer. For your first listing, choose **Normal** (`sla_sigma_x ≈ 0.5`) unless your uptime history is volatile — see [Confidence values](#confidence-values) for risk tradeoffs. 5. Save and confirm the SLA charge preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 60d86648..c206efbc 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -181,7 +181,27 @@ result = client.create_instance( print(result) ``` -**SLA via REST:** `create_instance()` cannot set `target_reliability`. To enable the SLA, rent with REST and pass the same target you searched with: +**SLA via REST:** `create_instance()` cannot set `target_reliability`. If you only use Python, rent with REST and pass the same target you searched with: + +```python +import requests + +offer_id = 12345 # offer/ask ID from search, not a running instance ID +response = requests.put( + f"https://console.vast.ai/api/v0/asks/{offer_id}/", + headers={"Authorization": "Bearer YOUR_API_KEY"}, + json={ + "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", + "disk": 50, + "target_reliability": 0.95, + }, + timeout=60, +) +response.raise_for_status() +print(response.json()) # new_contract is the rental instance ID +``` + +The same call with curl: ```bash curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ From 7851b8ab3864ab97cafa1f744808054497106e0f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 08:36:54 -0700 Subject: [PATCH 058/250] docs(sla): address doc-review consensus (cycle 14) Separate REST and CLI pagination defaults and point CLI search at a REST or console rent path for the SLA. Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 4 +++- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 7 +++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 0017de99..860024bc 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -6,7 +6,9 @@ sidebarTitle: "create instance" Create a new instance -**SLA:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable SLA. See [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**SLA:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable the SLA. See [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). + +**Rent with an SLA (REST):** After searching with a reliability target, rent with `PUT /api/v0/asks/{offer_id}/` and `target_reliability` set. See the [client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe) and [API automation](/guides/instances/choosing/sla-coverage#api-automation). ## Usage diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index fab93770..c0b74f7e 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -78,7 +78,7 @@ bool = True | False ## Examples -**Search quotes SLA pricing only.** `vastai create instance` cannot pass `target_reliability` today — use the web console or REST to enable the SLA; see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**Search quotes SLA pricing only.** `vastai create instance` cannot pass `target_reliability` today — use the web console or REST to enable the SLA; see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). When `target_reliability` is set, prefer `dph_total` (and `--order dph_total`) over `dph` for the all-in price. ```bash diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d52cbf41..5e0baad3 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -43,7 +43,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | -| I use only the CLI today | **Cannot enable SLA at rent time** — CLI search only quotes pricing. After rent, verify with `vastai show instances-v1 --raw` (`target_reliability` > 0). To enable the SLA, use the console or [API automation](#api-automation) (REST) | +| I use only the CLI today | **Cannot enable the SLA at rent time** — CLI search only quotes pricing. From `vastai search offers --raw`, use `offers[].id` as the ask id, then rent in the console or with `PUT /api/v0/asks/{id}/` and the same `target_reliability` ([API automation](#api-automation)). After rent, verify with `vastai show instances-v1 --raw` (`target_reliability` > 0) | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | | Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | | View service credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | @@ -225,7 +225,10 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). -**3. Verify** via `GET /api/v1/instances/` or `vastai show instances-v1 --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. Pass an explicit `limit` (default can be as low as **5**; maximum **25** per request). Paginate by passing each response’s `next_token` as the **`after_token`** query parameter until `next_token` is null. On the CLI, use `--limit` and `--next-token` with `show instances-v1`. +**3. Verify** via `GET /api/v1/instances/` or `vastai show instances-v1 --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. + +- **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). The server default `limit` can be as low as **5** (maximum **25**). +- **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. **Billing reconciliation (console):** confirming the SLA does not show service credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. From 8a1bcabdee355c39958b24130e8efb89fca21f0a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 08:41:29 -0700 Subject: [PATCH 059/250] docs(sla): address doc-review consensus (cycle 15) Point console users past the scoped-key JSON and tell REST renters to keep storage numbers aligned. Co-authored-by: Cursor --- api-reference/permissions.mdx | 8 ++++---- cli/reference/create-instance.mdx | 2 +- sdk/python/reference/create-instance.mdx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index e2b7f4fa..13bccf26 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -66,9 +66,9 @@ You can create scoped keys using: **Console-only users** do not need a scoped API key to rent or list with SLA. These recipes are for REST and CLI automation. -**Renters (clients):** Use the [client SLA recipe](#client-sla-scoped-key-recipe) only — `misc`, `instance_read`, and `instance_write` together. Start with [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). Do not copy the host recipe. +**Renters (clients):** Use the [client SLA recipe](#client-sla-scoped-key-recipe) only — `misc`, `instance_read`, and `instance_write` together (the full task table is under `misc`). Start with [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). Do not copy the host recipe. You do not need a scoped API key to rent with an SLA in the web console. -**Hosts (providers):** Use every category in the [host SLA recipe](#host-sla-scoped-key-recipe). `machine_write` by itself is not enough. Add `misc` if you verify the listing with search offers. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). Do not copy the client recipe. +**Hosts (providers):** Use every category in the [host SLA recipe](#host-sla-scoped-key-recipe) (the full task table is under `machine_write`). `machine_write` by itself is not enough. Add `misc` if you verify the listing with search offers. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). Do not copy the client recipe. Skip that JSON if you only use **Set Pricing → SLA** in the console. On this page, **client** means renter and **provider** means host. @@ -220,7 +220,7 @@ Below is the complete mapping of which endpoints each permission category contro -**Host only — minimum SLA API key.** Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. Enable every category in the JSON below. `machine_write` by itself cannot backtest, list, and read earnings. +**Host only — minimum SLA API key.** Skip this JSON if you only use **Set Pricing → SLA** in the console. Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. Enable every category in the JSON below. `machine_write` by itself cannot backtest, list, and read earnings. ```json { @@ -260,7 +260,7 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user -**Client (renter) only — search and REST rent.** Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). +**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). ```json { diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 860024bc..25891dce 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -8,7 +8,7 @@ Create a new instance **SLA:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable the SLA. See [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). -**Rent with an SLA (REST):** After searching with a reliability target, rent with `PUT /api/v0/asks/{offer_id}/` and `target_reliability` set. See the [client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe) and [API automation](/guides/instances/choosing/sla-coverage#api-automation). +**Rent with an SLA (REST):** After searching with a reliability target, rent with `PUT /api/v0/asks/{offer_id}/` and `target_reliability` set. Use the same storage number in CLI search (`--storage`), REST search (`allocated_storage`), and the rent body (`disk`). See the [client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe) and [API automation](/guides/instances/choosing/sla-coverage#api-automation). ## Usage diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index c206efbc..184d89e6 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create_instance" Create a new instance from an offer/ask ID returned by search. -**SLA:** `target_reliability` is not available on `create_instance()` today. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). +**SLA:** `target_reliability` is not available on `create_instance()` today. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). ## Signature From b1199bdafed77fc967e8d081da9cab9bb90da46e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 08:49:09 -0700 Subject: [PATCH 060/250] docs(sla): address doc-review consensus (cycle 16) Correct the renter scoped-key pointer and name the SLA fee, SLA charge, and slaPremiumPerHour as the same amount. Co-authored-by: Cursor --- api-reference/permissions.mdx | 12 +++++++++++- guides/instances/choosing/sla-coverage.mdx | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 13bccf26..2dd73774 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -7,6 +7,10 @@ Every API key has a set of permissions that control which endpoints it can acces For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). + +**Renting with an SLA via API?** Jump to the [client SLA scoped-key recipe](#client-sla-scoped-key-recipe). Console renters start with [SLA](/guides/instances/choosing/sla-coverage) and return here only when they need an automation key. + + ## Permission Categories Permissions are organized into categories. When you create a scoped API key, you include only the categories the key needs. The available categories are: @@ -66,7 +70,7 @@ You can create scoped keys using: **Console-only users** do not need a scoped API key to rent or list with SLA. These recipes are for REST and CLI automation. -**Renters (clients):** Use the [client SLA recipe](#client-sla-scoped-key-recipe) only — `misc`, `instance_read`, and `instance_write` together (the full task table is under `misc`). Start with [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). Do not copy the host recipe. You do not need a scoped API key to rent with an SLA in the web console. +**Renters (clients):** Use the [client SLA recipe](#client-sla-scoped-key-recipe) only. It lists the minimum categories: `misc` for search, `instance_write` for rent, and `instance_read` for verification. There is no separate task table under the `misc` endpoint list — follow the client recipe JSON and table. Start with [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). Do not copy the host recipe. You do not need a scoped API key to rent with an SLA in the web console. **Hosts (providers):** Use every category in the [host SLA recipe](#host-sla-scoped-key-recipe) (the full task table is under `machine_write`). `machine_write` by itself is not enough. Add `misc` if you verify the listing with search offers. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). Do not copy the client recipe. Skip that JSON if you only use **Set Pricing → SLA** in the console. @@ -274,6 +278,12 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user This is the minimum for search, REST rent, and verification. Add `user_read` if the flow loads templates or account profile data, and `user_write` if it creates SSH keys or templates. See the instance-management example under [Creating Scoped Keys](#creating-scoped-keys). +| Task | Category | Console fallback | +| --- | --- | --- | +| Search SLA offers | `misc` | **Search** | +| Rent with an SLA | `instance_write` | Console **RENT** | +| Verify `target_reliability` | `instance_read` | **Instances** | + **Service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 5e0baad3..2d3399d9 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -25,7 +25,7 @@ A few things people mix up: - The GPU bill does **not** stop during an outage. SLA pays you back later as a credit, usually after the next UTC midnight. - A search filter does **not** turn on an SLA. You have to set a reliability target when you rent, in the web console or with the API. The CLI cannot turn SLA on today. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. -- If the price breakdown has **no SLA fee line**, you do not have an SLA. +- If the price breakdown has **no SLA fee line**, you do not have an SLA. The console may also label that line **SLA charge**. In API responses the same amount is `slaPremiumPerHour`. Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). @@ -43,7 +43,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | -| I use only the CLI today | **Cannot enable the SLA at rent time** — CLI search only quotes pricing. From `vastai search offers --raw`, use `offers[].id` as the ask id, then rent in the console or with `PUT /api/v0/asks/{id}/` and the same `target_reliability` ([API automation](#api-automation)). After rent, verify with `vastai show instances-v1 --raw` (`target_reliability` > 0) | +| I use only the CLI today | Search can quote an SLA. Enabling it requires the console or [API automation](#api-automation). `vastai create instance` does not set `target_reliability`. | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | | Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | | View service credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | From d1b07b3df507b04bd6c6b798eb471cd8944abf59 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 08:53:34 -0700 Subject: [PATCH 061/250] docs(sla): address doc-review consensus (cycle 17) Clarify that create_asks success IDs update the listing, not locked SLA terms on active rentals. Co-authored-by: Cursor --- host/sla-offers.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 17cdfae9..a472dfa7 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -403,7 +403,11 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ ``` - `extended` — integer count of rental contracts extended (read from `results[0]`, not the top level) -- `new_contracts` / `upd_contracts` — arrays of contract IDs +- `new_contracts` / `upd_contracts` — arrays of listing contract IDs, not a signal that locked SLA terms on an active rental changed + + +SLA field updates apply to the **offer** and to **new** rentals only. Existing rental contracts keep their locked reliability target and SLA fee until they end. `upd_contracts` and `new_contracts` describe listing maintenance, not changes to an active renter's locked SLA terms. + ## Economics walkthrough From 6fb6397087bdf38e0ab588c6e1aa21b3d361f63e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 09:01:42 -0700 Subject: [PATCH 062/250] docs(sla): address doc-review consensus (cycle 18) State that create_asks keeps omitted listing fields, and narrow the SDK list_machine note to CLI-only volume and duration flags. Co-authored-by: Cursor --- api-reference/openapi.yaml | 13 ++++++++----- api-reference/openapi/yaml/list_machine.yaml | 3 ++- snippets/host/sdk/list-machine.mdx | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 84b60f05..92160774 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4525,11 +4525,14 @@ paths: summary: list machine description: "Creates or updates ask contracts for a machine to list it for\ \ rent on the vast.ai platform.\nAllows setting offer pricing, rental types,\ - \ end dates, discount rates, and SLA parameters.\n\nSLA request-body fields\ - \ (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on\ - \ this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target`\ - \ / legacy `sla_reliability` are ignored \u2014 clients choose coverage at\ - \ search/rent time. The published CLI and SDK do not yet expose SLA fields\ + \ end dates, discount rates, and SLA parameters.\nUnspecified fields keep\ + \ their current listing values (partial update). For an SLA-only change, send\ + \ the machine id plus SLA fields. Read the current offer with show machines\ + \ before changing pricing or the end date.\n\nSLA request-body fields (`sla_r_claim`,\ + \ `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint.\ + \ SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy\ + \ `sla_reliability` are ignored \u2014 clients choose a reliability target\ + \ at search/rent time. The published CLI and SDK do not yet expose SLA fields\ \ \u2014 use the host console (**Set Pricing \u2192 SLA**) or REST/`curl`\ \ until CLI/SDK support ships.\n\nCLI Usage (non-SLA fields): `vastai list\ \ machine [options]`" diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 52d59d7d..960b0f4b 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -13,8 +13,9 @@ paths: description: | Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. + Unspecified fields keep their current listing values (partial update). For an SLA-only change, send the machine id plus SLA fields. Read the current offer with show machines before changing pricing or the end date. - SLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are ignored — clients choose coverage at search/rent time. The published CLI and SDK do not yet expose SLA fields — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. + SLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are ignored — clients choose a reliability target at search/rent time. The published CLI and SDK do not yet expose SLA fields — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. CLI Usage (non-SLA fields): `vastai list machine [options]` security: diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 583ab8e8..36df70f3 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration listing options are CLI-only today. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `end_date` is on this method and on that REST call. Volume size, volume price, and duration flags that are not parameters here (`-v`, `-z`, `-l` on the CLI) are CLI-only today. ## Signature @@ -57,7 +57,7 @@ VastAI.list_machine( ## Returns -`str`, Result from the API call. +`str`. The return value is the API response body as text (JSON). ## Example From ed918ff8c21987117cab8d83f359a9875066d1c4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 09:43:14 -0700 Subject: [PATCH 063/250] docs(sla): address doc-review consensus (cycle 19) Require a reliability target before rent, and send SLA credits to console billing instead of the Charges API. Co-authored-by: Cursor --- api-reference/permissions.mdx | 13 ++++++++++--- guides/instances/choosing/find-and-rent.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 6 +++--- host/sla-backtester.mdx | 4 +++- host/sla-offers.mdx | 4 +++- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 2dd73774..6fce7951 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -8,7 +8,7 @@ Every API key has a set of permissions that control which endpoints it can acces For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). -**Renting with an SLA via API?** Jump to the [client SLA scoped-key recipe](#client-sla-scoped-key-recipe). Console renters start with [SLA](/guides/instances/choosing/sla-coverage) and return here only when they need an automation key. +**Renting with an SLA via API?** Jump to the [client SLA scoped-key recipe](#client-sla-scoped-key-recipe). **Offering an SLA via API?** Jump to the [host SLA scoped-key recipe](#host-sla-scoped-key-recipe). Console users start with [SLA](/guides/instances/choosing/sla-coverage) or [SLA Offers](/host/sla-offers) and return here only when they need an automation key. ## Permission Categories @@ -68,7 +68,7 @@ You can create scoped keys using: ### SLA workflows (scoped keys) -**Console-only users** do not need a scoped API key to rent or list with SLA. These recipes are for REST and CLI automation. +**Console-only users** do not need a scoped API key to rent or list with an SLA. These recipes are for REST and CLI automation. **Renters (clients):** Use the [client SLA recipe](#client-sla-scoped-key-recipe) only. It lists the minimum categories: `misc` for search, `instance_write` for rent, and `instance_read` for verification. There is no separate task table under the `misc` endpoint list — follow the client recipe JSON and table. Start with [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). Do not copy the host recipe. You do not need a scoped API key to rent with an SLA in the web console. @@ -135,6 +135,13 @@ You can also use **wildcards** in `params` to represent placeholder values, usef ## Endpoint Reference by Category +**Console users** do not need this catalog to use an SLA. Start with [SLA](/guides/instances/choosing/sla-coverage) (renters) or [SLA Offers](/host/sla-offers) (hosts). + +**Automators:** copy the scoped key for your role before you scan the endpoint lists: + +- Renters: [client SLA scoped-key recipe](#client-sla-scoped-key-recipe) (in **misc** below) +- Hosts: [host SLA scoped-key recipe](#host-sla-scoped-key-recipe) (in **machine_write** below) + Below is the complete mapping of which endpoints each permission category controls. ### instance\_read @@ -264,7 +271,7 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user -**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). +**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). After rent, verify `target_reliability` and the SLA fee (`slaPremiumPerHour`) with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (`instance_read`). Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. ```json { diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 3a30cafa..ea9a6e76 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -8,7 +8,7 @@ description: Find and rent GPU instances on Vast.ai. Learn how to search, filter The search page is the main portal for finding good machines and creating instances on them. -Before renting an instance, you'll need to select a template that defines your Docker image and connection method. If you haven't already, review [Choosing a Template](/guides/instances/choosing/templates) to understand your options. +Before renting an instance, you'll need to select a template that defines your Docker image and connection method. If you haven't already, review [Choosing a Template](/guides/instances/choosing/templates) to understand your options. Add a payment method or account credit under **Account → Billing** if rent fails for lack of balance. # Page Walkthrough @@ -58,7 +58,7 @@ All stats shown are the portion of the total machine rented. - Max Duration: The maximum length of a rental contract on this machine - Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host reliability commitment. - Rental Option: RENT button -- **SLA (optional):** On-demand offers may include an optional SLA upsell. The host’s advertised reliability commitment (not the Reliability Score above) sets the ceiling for your target. Confirm an **SLA charge** line before **RENT** — see [SLA](/guides/instances/choosing/sla-coverage). +- **SLA (optional):** On-demand offers may include an optional SLA. Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 2d3399d9..c49701d0 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -297,15 +297,15 @@ Production settlement uses the multi-window reliability blend described above, n ### Settlement timing -- Settlement runs **once per day** for the previous billing day. -- Credits accumulate on your instance charges and transfer to your account balance. +- Settlement runs **once per day** for the previous billing day (UTC). +- Service credits post to your **account balance**. View them under **Account → Billing** in the console. They do **not** appear as `items[].type` on `GET /api/v0/charges/`. Do not use the Charges API or `show charges` to reconcile SLA credits. - When your contract ends, any remaining unsettled days are resolved at close. ## If your instance goes down 1. Save work and check **Instances** for host/maintenance status. 2. Remember: compute and SLA charges continue until settlement; credits apply to the **previous UTC day**, not the current hour. -3. After settlement, check **Account → Billing** (Charges / billing history) for SLA line items. +3. After settlement, check **Account → Billing** in the console for SLA line items (not `GET /api/v0/charges/`). 4. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). ## Viewing SLA on active instances diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 26c7d404..11249ea9 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -4,7 +4,9 @@ description: "Replay your machine's historical earnings through SLA math to prev "canonical": "/host/sla-backtester" --- -The **SLA (Service Level Agreement) earnings backtester** lets you answer a practical question before you list: *if clients had rented with reliability target **`r`** and I offered SLA at confidence **`p`**, how would that have affected my earnings on this machine over the last few months?* +The **SLA (Service Level Agreement) earnings backtester** is for hosts. Renters should use [SLA](/guides/instances/choosing/sla-coverage). + +It lets you answer a practical question before you list: *if clients had rented with reliability target **`r`** and I offered an SLA at confidence **`p`**, how would that have affected my earnings on this machine over the last few months?* **Console hosts:** use **Set Pricing → SLA** in the web console to preview SLA charges — you do not need this API. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a472dfa7..7a187b08 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -18,6 +18,8 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative ## Choose your path +Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. + | Goal | Start here | | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | @@ -501,7 +503,7 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi ### Scheduled maintenance -**Planned SLA maintenance (may earn credit):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for SLA credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. Credit eligibility is evaluated on a case-by-case basis. +**Planned SLA maintenance (may earn a service credit):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for service-credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. A service credit is not guaranteed. Renters should check **Instances** for status. Credited maintenance is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. Credit eligibility is evaluated on a case-by-case basis. **CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** Schedule maintenance **sequentially** across a fleet. On HTTP 429, wait and retry with backoff (for example, `sleep 2` between machines). See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). From 80be2f668dd61fbeff9560a7a339747b9c8004f7 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 09:48:22 -0700 Subject: [PATCH 064/250] docs(sla): address doc-review consensus (cycle 20) Label the fleet loop as a re-list of machines that already have an SLA, and match rent error codes to the API. Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-offers.mdx | 4 +++- sdk/python/reference/create-instance.mdx | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 25891dce..cc1637a5 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -8,7 +8,7 @@ Create a new instance **SLA:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable the SLA. See [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). -**Rent with an SLA (REST):** After searching with a reliability target, rent with `PUT /api/v0/asks/{offer_id}/` and `target_reliability` set. Use the same storage number in CLI search (`--storage`), REST search (`allocated_storage`), and the rent body (`disk`). See the [client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe) and [API automation](/guides/instances/choosing/sla-coverage#api-automation). +**Rent with an SLA (REST):** After searching with a reliability target, rent with `PUT /api/v0/asks/{id}/`. `{id}` is the offer/ask id from search. Set `target_reliability` on that request. Use the same storage number in CLI search (`--storage`), REST search (`allocated_storage`), and the rent body (`disk`). See the [client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe) and [API automation](/guides/instances/choosing/sla-coverage#api-automation). ## Usage diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c49701d0..121c7196 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -236,8 +236,8 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ | --- | --- | --- | | Target on a non-SLA offer | HTTP 400 `invalid_args` | Search with `has_sla=true`; confirm `expected_reliability` | | Target out of range / invalid | HTTP 400 `invalid_args` | Use `0 < target_reliability < 1`; stay at or below a realistic host reliability commitment | -| Offer unavailable / stale | HTTP 404 `invalid_args` (check `msg` for `no_such_ask`) | Re-search and rent a current offer ID | -| Cannot start immediately (`cancel_unavail`) | HTTP 410 `no_such_ask` | Offer cannot start now; pick another offer or retry later — see [Create Instance](/api-reference/instances/create-instance) | +| Offer not found or not available | HTTP 404 `invalid_args` (`msg` may include `no_such_ask`) | Do not retry that id; search again and rent a current offer | +| Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | | Channel | Default storage | Field | Units (label) | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 7a187b08..c1a46c3b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -307,7 +307,9 @@ Machine `id` may be a string in raw JSON. The response is wrapped in a `machines Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge → PUT). `vastai list machine` and the Python SDK listing helpers cannot set SLA fields; start from this REST pattern (or the console) when you move an existing CLI listing to SLA. -### Fleet listing workflow (advanced — fleet operators only) +### Fleet SLA re-list (machines that already have an SLA) + +This loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only re-publishes machines that already have `sla_r_claim > 0`. `PUT /api/v0/machines/create_asks/` publishes a live listing (same as **LIST**). Only run this loop on machines you intend to list or update. Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 184d89e6..c6a4c9d3 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -186,7 +186,7 @@ print(result) ```python import requests -offer_id = 12345 # offer/ask ID from search, not a running instance ID +offer_id = 12345 # path id: offer/ask ID from search, not a running instance ID response = requests.put( f"https://console.vast.ai/api/v0/asks/{offer_id}/", headers={"Authorization": "Bearer YOUR_API_KEY"}, From 2384e19d2d94d8dcd1798de0b8a665cefdff12e7 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 09:52:24 -0700 Subject: [PATCH 065/250] docs(sla): address doc-review consensus (cycle 21) Explain template rent versus the OpenAPI image field, and name the nested SLA fee fields on instances. Co-authored-by: Cursor --- api-reference/permissions.mdx | 6 ++++-- guides/instances/choosing/sla-coverage.mdx | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 6fce7951..80e46533 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -3,7 +3,9 @@ title: "Permissions" sidebarTitle: "Permissions" --- -Every API key has a set of permissions that control which endpoints it can access. This page is the comprehensive reference for permission categories, how they map to API routes, and how to build custom scoped keys. +Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. + +**Using an SLA from the console?** You do not need this catalog. Start with [SLA](/guides/instances/choosing/sla-coverage) or [SLA Offers](/host/sla-offers). Use this page when you automate with a scoped API key. For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). @@ -271,7 +273,7 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user -**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). After rent, verify `target_reliability` and the SLA fee (`slaPremiumPerHour`) with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (`instance_read`). Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. +**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). After rent, verify `target_reliability` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (`instance_read`). On a running instance the SLA fee is `instance.slaPremiumPerHour`. A search snapshot on that response uses `search.slaPremiumPerHour`. Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. ```json { diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 121c7196..cdff19ab 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -221,7 +221,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ }' ``` -`template_hash_id` is the content hash of a saved template. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). +`template_hash_id` is the content hash of a saved template. The template supplies the image, so this example omits `image`. OpenAPI still lists `image` in the schema `required` array, and the field description says `image` is optional when a template is present. If a client rejects the body for a missing `image`, add `"image"` with the template's container image. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). From 05f5c4ce412d7e6350ecaa43758bbd12b2d272b8 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 09:56:17 -0700 Subject: [PATCH 066/250] docs(sla): address doc-review consensus (cycle 22) Name the console Claim control as the reliability commitment, and use template_hash_id in the create-instance description. Co-authored-by: Cursor --- api-reference/openapi.yaml | 2 +- api-reference/openapi/yaml/create_instance.yaml | 2 +- cli/reference/search-offers.mdx | 2 +- host/sla-offers.mdx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 92160774..8f946a70 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1581,7 +1581,7 @@ paths: summary: create instance description: "Creates a new instance by accepting an \"ask\" contract from a\ \ provider.\n\n- Use the search offers endpoint to discover available machines.\n\ - - If `template_id` is provided, those template defaults are either merged\ + - If `template_hash_id` is provided, those template defaults are either merged\ \ or overridden by parameters specified in the request body.\n\n**Template\ \ Precedence Rules:**\n- **Scalar fields** (image, disk, runtype, etc.): Request\ \ value overrides template value\n- **`env`**: Merged by key. Request values\ diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 7db5e9ee..f5baedc0 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -14,7 +14,7 @@ paths: Creates a new instance by accepting an "ask" contract from a provider. - Use the search offers endpoint to discover available machines. - - If `template_id` is provided, those template defaults are either merged or overridden by parameters specified in the request body. + - If `template_hash_id` is provided, those template defaults are either merged or overridden by parameters specified in the request body. **Template Precedence Rules:** - **Scalar fields** (image, disk, runtype, etc.): Request value overrides template value diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index c0b74f7e..796b0f4e 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -167,7 +167,7 @@ vastai search offers 'cpu_arch=arm64' | `vms_enabled` | bool | is the machine a VM instance | -SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console or REST create-instance flow documented in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour` — see [SLA → Finding SLA offers](/guides/instances/choosing/sla-coverage#finding-sla-offers). Older CLI builds may print a stderr warning that a field is unrecognized while still applying the filter — prefer a current CLI, or ignore the warning when results look correct. +SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console or REST create-instance flow documented in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour` — see [SLA → Finding SLA offers](/guides/instances/choosing/sla-coverage#finding-sla-offers). If the CLI warns that an SLA search field is unrecognized, upgrade the CLI and check that the results still match the filters you set. ## Global Options diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index c1a46c3b..a2b569c5 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -216,7 +216,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. -4. Set **Claim** and **Confidence**. **Claim** in the console is your reliability commitment (`sla_r_claim`); renters see it as expected reliability on the offer. For your first listing, choose **Normal** (`sla_sigma_x ≈ 0.5`) unless your uptime history is volatile — see [Confidence values](#confidence-values) for risk tradeoffs. +4. Set your **reliability commitment** (the console control is **Claim**; the API field is `sla_r_claim`). Renters see it as expected reliability on the offer. Set **Confidence** too. For your first listing, choose **Normal** (`sla_sigma_x ≈ 0.5`) unless your uptime history is volatile — see [Confidence values](#confidence-values) for risk tradeoffs. 5. Save and confirm the SLA charge preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. From 0ce5e8e98f32179eb506324c7ca6718583705ec7 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:09:23 -0700 Subject: [PATCH 067/250] docs(sla): address doc-review consensus (cycle 23) Tell renters to use the offer id from search, and to match CLI storage with the create-instance disk size. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 80e46533..d442a966 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -273,7 +273,7 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user -**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). After rent, verify `target_reliability` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (`instance_read`). On a running instance the SLA fee is `instance.slaPremiumPerHour`. A search snapshot on that response uses `search.slaPremiumPerHour`. Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. +**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). After rent, verify `target_reliability` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (`instance_read`). On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. ```json { diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index cc1637a5..7adf26a3 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -8,7 +8,7 @@ Create a new instance **SLA:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable the SLA. See [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). -**Rent with an SLA (REST):** After searching with a reliability target, rent with `PUT /api/v0/asks/{id}/`. `{id}` is the offer/ask id from search. Set `target_reliability` on that request. Use the same storage number in CLI search (`--storage`), REST search (`allocated_storage`), and the rent body (`disk`). See the [client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe) and [API automation](/guides/instances/choosing/sla-coverage#api-automation). +**Rent with an SLA (REST):** After searching with a reliability target, rent with `PUT /api/v0/asks/{id}/`. `{id}` is `offers[].id` from search (not `bundle_id`). Set `target_reliability` on that request. Use the same storage number in CLI search (`--storage`), REST search (`allocated_storage`), and the rent body (`disk`). If you searched with `vastai search offers --storage N`, pass `--disk N` on `vastai create instance` (search defaults to 5 GiB; create instance defaults to 10 GB). See the [client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe) and [API automation](/guides/instances/choosing/sla-coverage#api-automation). ## Usage diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 796b0f4e..1a54dbc2 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -78,7 +78,7 @@ bool = True | False ## Examples -**Search quotes SLA pricing only.** `vastai create instance` cannot pass `target_reliability` today — use the web console or REST to enable the SLA; see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). When `target_reliability` is set, prefer `dph_total` (and `--order dph_total`) over `dph` for the all-in price. +**Search quotes SLA pricing only.** `vastai create instance` cannot pass `target_reliability` today — use the web console or REST to enable the SLA; see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). When `target_reliability` is set, prefer `dph_total` (and `--order dph_total`) over `dph` for the all-in price. If you set `--storage N` here, pass `--disk N` on `vastai create instance` (search defaults to 5 GiB; create instance defaults to 10 GB). ```bash diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index cdff19ab..bd3c2394 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -193,7 +193,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -**2. Rent** the chosen offer ID and pass the **same** target: +**2. Rent** the chosen offer. Use `offers[].id` (or `ask_contract_id`) from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Do not use `bundle_id`. Save `new_contract` from the rent response, then find that contract while paging `GET /api/v1/instances/` and read `target_reliability` and `instance.slaPremiumPerHour` on that row. Pass the **same** reliability target you searched with: ```bash curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ @@ -239,6 +239,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ | Offer not found or not available | HTTP 404 `invalid_args` (`msg` may include `no_such_ask`) | Do not retry that id; search again and rent a current offer | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | +| Too many requests | HTTP 429 | Wait and retry the same rent. The API may return `API requests too frequent` | | Channel | Default storage | Field | Units (label) | | --- | --- | --- | --- | From 83e332d4846f5425bb0e1d7a5bb513d6f0cb80ea Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:13:17 -0700 Subject: [PATCH 068/250] docs(sla): address doc-review consensus (cycle 24) Document rent as PUT, and point console users past the API sections they can skip. Co-authored-by: Cursor --- api-reference/openapi.yaml | 14 +++++++------- api-reference/openapi/build.py | 2 +- api-reference/openapi/yaml/search_offers.yaml | 10 +++++----- cli/reference/create-instance.mdx | 4 +--- guides/instances/choosing/sla-coverage.mdx | 2 ++ host/sla-backtester.mdx | 2 ++ 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 8f946a70..5076aa9e 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -11,7 +11,7 @@ info: \ CLI = GB; in REST API = MB (CLI auto-converts)\n- SSH keys must be registered\ \ BEFORE creating an instance (VM: no recovery; Docker: can add post-create)\n\ - `onstart` field is limited to 4048 characters -- gzip+base64 for longer scripts\n\ - - `POST /api/v0/asks/{id}/` (create instance) returns `new_contract` as the instance\ + - `PUT /api/v0/asks/{id}/` (create instance) returns `new_contract` as the instance\ \ ID, not `id`\n- Poll trap: if `actual_status` becomes `exited`, `unknown`, or\ \ `offline` it will never reach `running` -- destroy and retry" version: 1.0.0 @@ -6654,15 +6654,15 @@ paths: reliability: type: object description: 'Historical machine reliability score (0-1), not the - host SLA claim. Example: {"gte": 0.99}' + host reliability commitment. Example: {"gte": 0.99}' target_reliability: type: object - description: "Client SLA coverage target. Value must be greater\ + description: "Reliability target for an SLA. Value must be greater\ \ than 0 and less than 1 (exclusive bounds \u2014\nsame as create-instance).\ - \ When set, search prices include the SLA charge in dph_total\ - \ and\nreturns search.slaPremiumPerHour. Pass the same target\ - \ again on PUT /api/v0/asks/{id}/ to\nenable coverage. Example:\ - \ {\"eq\": 0.95}\n" + \ When set, search prices include the SLA fee in dph_total and\n\ + returns search.slaPremiumPerHour (the API name for that fee).\ + \ Pass the same target again on PUT /api/v0/asks/{id}/ to\nenable\ + \ the SLA. Example: {\"eq\": 0.95}\n" has_sla: type: object description: 'Restrict to offers with SLA enabled (true) or without diff --git a/api-reference/openapi/build.py b/api-reference/openapi/build.py index 00239b06..5fb00b10 100644 --- a/api-reference/openapi/build.py +++ b/api-reference/openapi/build.py @@ -162,7 +162,7 @@ def build_master_doc(): "- `gpu_ram` in CLI = GB; in REST API = MB (CLI auto-converts)\n" "- SSH keys must be registered BEFORE creating an instance (VM: no recovery; Docker: can add post-create)\n" "- `onstart` field is limited to 4048 characters -- gzip+base64 for longer scripts\n" - "- `POST /api/v0/asks/{id}/` (create instance) returns `new_contract` as the instance ID, not `id`\n" + "- `PUT /api/v0/asks/{id}/` (create instance) returns `new_contract` as the instance ID, not `id`\n" "- Poll trap: if `actual_status` becomes `exited`, `unknown`, or `offline` it will never reach `running` -- destroy and retry" ), 'version': '1.0.0', diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index ea2b6f91..66a9efc4 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -88,14 +88,14 @@ paths: example: ["RTX_3090", "RTX_4090"] reliability: type: object - description: 'Historical machine reliability score (0-1), not the host SLA claim. Example: {"gte": 0.99}' + description: 'Historical machine reliability score (0-1), not the host reliability commitment. Example: {"gte": 0.99}' target_reliability: type: object description: | - Client SLA coverage target. Value must be greater than 0 and less than 1 (exclusive bounds — - same as create-instance). When set, search prices include the SLA charge in dph_total and - returns search.slaPremiumPerHour. Pass the same target again on PUT /api/v0/asks/{id}/ to - enable coverage. Example: {"eq": 0.95} + Reliability target for an SLA. Value must be greater than 0 and less than 1 (exclusive bounds — + same as create-instance). When set, search prices include the SLA fee in dph_total and + returns search.slaPremiumPerHour (the API name for that fee). Pass the same target again on PUT /api/v0/asks/{id}/ to + enable the SLA. Example: {"eq": 0.95} has_sla: type: object description: | diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 7adf26a3..287cc9d1 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -6,9 +6,7 @@ sidebarTitle: "create instance" Create a new instance -**SLA:** `target_reliability` is not available on this CLI command. Searching with a reliability target only quotes pricing — use the web console or REST create-instance to enable the SLA. See [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). - -**Rent with an SLA (REST):** After searching with a reliability target, rent with `PUT /api/v0/asks/{id}/`. `{id}` is `offers[].id` from search (not `bundle_id`). Set `target_reliability` on that request. Use the same storage number in CLI search (`--storage`), REST search (`allocated_storage`), and the rent body (`disk`). If you searched with `vastai search offers --storage N`, pass `--disk N` on `vastai create instance` (search defaults to 5 GiB; create instance defaults to 10 GB). See the [client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe) and [API automation](/guides/instances/choosing/sla-coverage#api-automation). +**SLA:** This command cannot set `target_reliability`. Searching only quotes an SLA. If you searched with `--storage N`, pass `--disk N` here (search defaults to 5 GiB; this command defaults to 10 GB). See [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation). ## Usage diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index bd3c2394..cddb845b 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -48,6 +48,8 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua | Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | | View service credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | +**Console renters:** You can stop after [In the web console](#in-the-web-console). You do not need an API key to turn on an SLA. + SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 11249ea9..59fe4c89 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -290,6 +290,8 @@ For missing or invalid API keys and permission denials (`machine_read`), see [Au ## Fleet workflow +Optional. Skip this section unless you automate many machines. Console hosts can use **Set Pricing → SLA** and a single request instead of the loop below. + This section is for hosts automating fleet review. Console-only hosts can run the baseline `curl` once per machine instead. ```bash From 4785b1b0350f3641d899c1d302f29a4a1ce53acf Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:16:54 -0700 Subject: [PATCH 069/250] docs(sla): address doc-review consensus (cycle 25) Put host and renter SLA key recipes in one table, and note that misc is broader than search. Co-authored-by: Cursor --- api-reference/permissions.mdx | 7 ++++++- snippets/host/sdk/list-machine.mdx | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index d442a966..a053c157 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -72,6 +72,11 @@ You can create scoped keys using: **Console-only users** do not need a scoped API key to rent or list with an SLA. These recipes are for REST and CLI automation. +| Role | Recipe | +| --- | --- | +| Renter automating search, rent, and verify | [Client SLA recipe](#client-sla-scoped-key-recipe) | +| Host automating list, backtest, and earnings | [Host SLA recipe](#host-sla-scoped-key-recipe) | + **Renters (clients):** Use the [client SLA recipe](#client-sla-scoped-key-recipe) only. It lists the minimum categories: `misc` for search, `instance_write` for rent, and `instance_read` for verification. There is no separate task table under the `misc` endpoint list — follow the client recipe JSON and table. Start with [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). Do not copy the host recipe. You do not need a scoped API key to rent with an SLA in the web console. **Hosts (providers):** Use every category in the [host SLA recipe](#host-sla-scoped-key-recipe) (the full task table is under `machine_write`). `machine_write` by itself is not enough. Add `misc` if you verify the listing with search offers. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). Do not copy the client recipe. Skip that JSON if you only use **Set Pricing → SLA** in the console. @@ -233,7 +238,7 @@ Below is the complete mapping of which endpoints each permission category contro -**Host only — minimum SLA API key.** Skip this JSON if you only use **Set Pricing → SLA** in the console. Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. Enable every category in the JSON below. `machine_write` by itself cannot backtest, list, and read earnings. +**Host only — minimum SLA API key.** Skip this JSON if you only use **Set Pricing → SLA** in the console. Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. Enable every category in the JSON below. `machine_write` by itself cannot backtest, list, and read earnings. The **`misc`** category is broader than search: it also covers other routes such as serverless groups. You cannot limit `misc` to search only. Use a separate key for SLA scripts. ```json { diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 36df70f3..f72ffd32 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `end_date` is on this method and on that REST call. Volume size, volume price, and duration flags that are not parameters here (`-v`, `-z`, `-l` on the CLI) are CLI-only today. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation), [List Machine](/api-reference/machines/list-machine) for REST field names such as `vol_size`). `end_date` is on this method and on that REST call. Volume size, volume price, and duration flags that are not parameters here (`-v`, `-z`, `-l` on the CLI) are CLI-only today. ## Signature From 61a883635f32fe1b00b62c928b65f0e388231394 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:20:16 -0700 Subject: [PATCH 070/250] docs(sla): address doc-review consensus (cycle 26) State that CLI search only quotes an SLA, and stop telling hosts to send volume fields on the listing API. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 4 ++++ snippets/host/sdk/list-machine.mdx | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index a053c157..fc132d51 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -278,7 +278,7 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user -**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). After rent, verify `target_reliability` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (`instance_read`). On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. +**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). After rent, verify `target_reliability` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (`instance_read`). On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. There is no search-only permission. **`misc`** also includes other routes, such as serverless. Use a dedicated key for SLA automation if you do not want that key to cover those routes. ```json { diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 287cc9d1..680cf94d 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -131,7 +131,7 @@ vastai create instance ID [OPTIONS] [--args ...] Performs the same action as pressing the "RENT" button on the website at https://cloud.vast.ai/create/ Creates an instance from an offer ID (which is returned from "search offers"). Each offer ID can only be used to create one instance. -Besides the offer ID, you must pass in an '`--image`' argument as a minimum. +Besides the offer ID, you must pass either `--image` or `--template_hash`. A template supplies the image. `vastai create instance` cannot set `target_reliability`. If you use args/entrypoint launch mode, we create a container from your image as is, without attempting to inject SSH or Jupyter. If you use the args launch mode, you can override the entrypoint with `--entrypoint`, and pass arguments to the entrypoint with `--args`. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 1a54dbc2..1199b4a4 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -5,6 +5,10 @@ sidebarTitle: "search offers" Search for instance types using custom query + +Search can quote an SLA. The CLI cannot turn an SLA on when you rent. Use the web console or REST with `target_reliability`. See [SLA](/guides/instances/choosing/sla-coverage). + + ## Usage ```bash diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index f72ffd32..b8f6cb33 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation), [List Machine](/api-reference/machines/list-machine) for REST field names such as `vol_size`). `end_date` is on this method and on that REST call. Volume size, volume price, and duration flags that are not parameters here (`-v`, `-z`, `-l` on the CLI) are CLI-only today. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `end_date` is on this method and on that REST call. Volume size, volume price, and duration flags (`-v`, `-z`, `-l` on the CLI) are CLI-only today. Do not send `vol_size`, `vol_price`, or a duration field on that REST call unless the [List Machine](/api-reference/machines/list-machine) schema documents them. ## Signature From 467ddb19f38809d5074f9b4e04bb2f85e867f70f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:24:06 -0700 Subject: [PATCH 071/250] docs(sla): address doc-review consensus (cycle 27) Spell out the CLI search-then-rent path so search filters are not mistaken for an active SLA. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index fc132d51..f8edb2e6 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -77,7 +77,7 @@ You can create scoped keys using: | Renter automating search, rent, and verify | [Client SLA recipe](#client-sla-scoped-key-recipe) | | Host automating list, backtest, and earnings | [Host SLA recipe](#host-sla-scoped-key-recipe) | -**Renters (clients):** Use the [client SLA recipe](#client-sla-scoped-key-recipe) only. It lists the minimum categories: `misc` for search, `instance_write` for rent, and `instance_read` for verification. There is no separate task table under the `misc` endpoint list — follow the client recipe JSON and table. Start with [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). Do not copy the host recipe. You do not need a scoped API key to rent with an SLA in the web console. +**Renters (clients):** Open the [client SLA recipe](#client-sla-scoped-key-recipe) for the JSON and task table. Use `misc` for search, `instance_write` for rent, and `instance_read` for verification. Do not copy the host recipe. You do not need a scoped API key to rent with an SLA in the web console. **Hosts (providers):** Use every category in the [host SLA recipe](#host-sla-scoped-key-recipe) (the full task table is under `machine_write`). `machine_write` by itself is not enough. Add `misc` if you verify the listing with search offers. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). Do not copy the client recipe. Skip that JSON if you only use **Set Pricing → SLA** in the console. @@ -255,7 +255,7 @@ Below is the complete mapping of which endpoints each permission category contro | Task | Permission | Console fallback | | --- | --- | --- | -| List/update SLA via `create_asks` | `machine_write` | **Set Pricing → SLA** → LIST | +| List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA**, then **LIST** | | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | None (CLI/REST only) | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index cddb845b..f5d55f33 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -50,6 +50,12 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua **Console renters:** You can stop after [In the web console](#in-the-web-console). You do not need an API key to turn on an SLA. +**CLI-only workflow** + +1. Search with SLA filters (`has_sla`, `target_reliability`) to see the quoted SLA fee. +2. The SLA starts only after you rent in the console (set **Reliability target**, then confirm the **SLA fee** in the price breakdown) or with REST `PUT /api/v0/asks/{id}/` and `target_reliability`. +3. `vastai create instance` by itself does not turn on an SLA. + SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). From f2880e3780dadf1a097125e55b56c4712aa8aa37 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:28:07 -0700 Subject: [PATCH 072/250] docs(sla): address doc-review consensus (cycle 28) Note that an SLA applies only to on-demand rent, not bid or interruptible offers. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index f5d55f33..228a189b 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -248,6 +248,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | | Too many requests | HTTP 429 | Wait and retry the same rent. The API may return `API requests too frequent` | +| SLA with a bid or interruptible offer | Rent does not turn on an SLA | Search with `"type": "ondemand"`. Do not send `price` or `bid_price` when you want an SLA. | | Channel | Default storage | Field | Units (label) | | --- | --- | --- | --- | From 207e567144ac77bc8893b57133d6e67d2301ad4e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:38:38 -0700 Subject: [PATCH 073/250] docs(sla): address doc-review consensus (cycle 29) Point console hosts and renters to the web steps before the API recipes. Co-authored-by: Cursor --- api-reference/permissions.mdx | 24 ++++++++++++++-------- guides/instances/choosing/sla-coverage.mdx | 21 ++++++++++++++++--- host/sla-offers.mdx | 6 ++++++ 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index f8edb2e6..442b5e3e 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -5,13 +5,17 @@ sidebarTitle: "Permissions" Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. -**Using an SLA from the console?** You do not need this catalog. Start with [SLA](/guides/instances/choosing/sla-coverage) or [SLA Offers](/host/sla-offers). Use this page when you automate with a scoped API key. +## You are here if… -For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). +| If you… | Start here | API key needed? | +| --- | --- | --- | +| Rent with an SLA in the **web console** | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) | No | +| List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) | No | +| Automate search, rent, or a host listing | [Client SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | - -**Renting with an SLA via API?** Jump to the [client SLA scoped-key recipe](#client-sla-scoped-key-recipe). **Offering an SLA via API?** Jump to the [host SLA scoped-key recipe](#host-sla-scoped-key-recipe). Console users start with [SLA](/guides/instances/choosing/sla-coverage) or [SLA Offers](/host/sla-offers) and return here only when they need an automation key. - +Console users do not need **Endpoint Reference by Category** unless they are scoping a key for automation. + +For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). ## Permission Categories @@ -142,9 +146,7 @@ You can also use **wildcards** in `params` to represent placeholder values, usef ## Endpoint Reference by Category -**Console users** do not need this catalog to use an SLA. Start with [SLA](/guides/instances/choosing/sla-coverage) (renters) or [SLA Offers](/host/sla-offers) (hosts). - -**Automators:** copy the scoped key for your role before you scan the endpoint lists: +**Automators:** copy the scoped key for your role before you scan the endpoint lists. Console users: use the [table at the top of this page](#you-are-here-if). - Renters: [client SLA scoped-key recipe](#client-sla-scoped-key-recipe) (in **misc** below) - Hosts: [host SLA scoped-key recipe](#host-sla-scoped-key-recipe) (in **machine_write** below) @@ -278,7 +280,11 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user -**Client (renter) only — search and REST rent.** You do not need a scoped API key to rent with an SLA in the web console. Create via [Create API Key](/api-reference/accounts/create-api-key) with the `api` wrapper below. `misc` is required for offer search (`POST /api/v0/bundles/`, CLI `search offers`). After rent, verify `target_reliability` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (`instance_read`). On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. There is no search-only permission. **`misc`** also includes other routes, such as serverless. Use a dedicated key for SLA automation if you do not want that key to cover those routes. +**Client (renter) only — search and REST rent.** You do not need this JSON to rent in the web console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. + +- **Search:** `misc` for `POST /api/v0/bundles/` and CLI `search offers`. There is no search-only permission. `misc` also covers other routes, such as serverless. Use a dedicated key if you do not want SLA automation to include those routes. +- **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. +- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. ```json { diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 228a189b..b8f6e0f9 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -48,7 +48,15 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua | Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | | View service credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | -**Console renters:** You can stop after [In the web console](#in-the-web-console). You do not need an API key to turn on an SLA. +**Console checklist (web only).** You do not need an API key. + +1. Open [Search](https://cloud.vast.ai/create/) and set **Reliability target**. Confirm **On-demand** is selected. +2. Confirm the price breakdown shows an **SLA fee** line before you rent. +3. Click **RENT**. An SLA does not apply to interruptible or bid rentals. +4. After rent, open **Instances** and confirm the SLA terms on the instance. +5. For service credits after downtime, check **Account → Billing**. They are not in the Charges API. + +Stop here unless you automate. The steps under [In the web console](#in-the-web-console) repeat this list with the same controls. [API automation](#api-automation) is for API keys. **CLI-only workflow** @@ -170,9 +178,16 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d ### API automation -**Prerequisites:** You should be comfortable with REST, an API key, and JSON. Otherwise stay on [In the web console](#in-the-web-console). Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. +**Console renters can stop after [In the web console](#in-the-web-console).** This section is for API keys. -Console-only renters can skip the rest of this section. +| Capability | Console | REST | +| --- | --- | --- | +| Search / quote an SLA | Yes | Yes (`POST /api/v0/bundles/`) | +| Enable an SLA at rent | Yes | Yes (`target_reliability` on `PUT /api/v0/asks/{id}/`) | +| Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | +| SLA service credits | **Account → Billing** | Not in `GET /api/v0/charges/` and not in client webhooks | + +**Prerequisites:** You should be comfortable with REST, an API key, and JSON. Otherwise stay on [In the web console](#in-the-web-console). Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. CLI and SDK `create instance` cannot set `target_reliability`. After a CLI/SDK search, complete the rental in the console (set Reliability target, then confirm an SLA charge line) or use the REST example below. If the instance has no SLA charge line, you do not have an SLA. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a2b569c5..265923d8 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -211,6 +211,8 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover ## Listing an SLA offer +**Console hosts:** use [Web console](#web-console) and, after you list, [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). [API (for automation)](#api-for-automation) and [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) are for API keys. + ### Web console 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. @@ -309,6 +311,10 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge ### Fleet SLA re-list (machines that already have an SLA) + +**Console hosts:** skip this section. Enable an SLA with [Web console](#web-console) and check settlement in [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). + + This loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only re-publishes machines that already have `sla_r_claim > 0`. `PUT /api/v0/machines/create_asks/` publishes a live listing (same as **LIST**). Only run this loop on machines you intend to list or update. Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. From 0fa168a7c18cc3a98cc5abfb971791913792097a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:42:59 -0700 Subject: [PATCH 074/250] docs(sla): address doc-review consensus (cycle 30) Warn that CLI search only quotes an SLA, and that the first create_asks example is not a new listing. Co-authored-by: Cursor --- api-reference/permissions.mdx | 6 +++++- cli/reference/search-offers.mdx | 2 ++ guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-offers.mdx | 12 ++++-------- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 442b5e3e..f0fbd458 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -13,7 +13,7 @@ Every API key has a set of permissions that control which endpoints it can acces | List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) | No | | Automate search, rent, or a host listing | [Client SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | -Console users do not need **Endpoint Reference by Category** unless they are scoping a key for automation. +On this page, **client** means renter and **provider** means host. Console users do not need **Endpoint Reference by Category** unless they are scoping a key for automation. For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). @@ -37,6 +37,10 @@ Permissions are organized into categories. When you create a scoped API key, you ## Creating Scoped Keys + +Renting or listing with an SLA in the web console does not require a scoped API key. Renters start at [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). Hosts start at [SLA Offers](/host/sla-offers#web-console). + + Define permissions as a JSON object and pass it when creating a key. The top-level key is always `"api"`, containing the categories you want to grant. **Example, Instance management with billing access:** diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 1199b4a4..daef7866 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -67,6 +67,8 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] **Query syntax** +The grammar below is for advanced filters. An SLA example is under [Examples](#examples). Search quotes an SLA; it does not turn one on (see the note at the top of this page). + ``` query = comparison comparison... comparison = field op value diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b8f6e0f9..49d2653c 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -34,7 +34,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua -`target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Searching with a target only quotes pricing — use the **web console** or **REST** create-instance to enable the SLA (see [Finding SLA offers](#finding-sla-offers)). +`vastai search offers` only quotes SLA pricing. `target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Use the **web console** or **REST** create-instance to enable the SLA (see [Finding SLA offers](#finding-sla-offers)). ## Choose your path diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 265923d8..561a3785 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -256,9 +256,9 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons 4. To enable SLA today, use `PUT /api/v0/machines/create_asks/` or **Set Pricing → SLA** in the console. The listing body field is `machine` (same ID as backtester `machine_id` and earnings `machid`). 5. For the full request/response schema, see [List Machine](/api-reference/machines/list-machine). - -The example below **adds SLA to an offer that already has base pricing configured**. For a first-time listing, include all required base fields (`price_gpu`, `end_date`, `min_chunk`, storage/bandwidth prices as needed) — see [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). - + +**Not a first listing.** The curl below adds SLA fields to a machine that already has base pricing. A first `create_asks` must also include `min_chunk` and typical disk and bandwidth prices. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). + ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ @@ -277,11 +277,7 @@ Replace `end_date` with a **future** Unix timestamp — past dates expire the of Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). - -Do not use the JSON below alone for a **first** listing. First-time `create_asks` requests must also include `min_chunk` and typical disk/bandwidth pricing — see [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). Use this as an **SLA-fields** reference when base pricing is already configured. - - -SLA fields example (existing listing): +SLA fields example (existing listing, same limit as the curl above): ```json { From 08199ab887c0a411f3948bfd7360f8cdbb295d34 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:47:53 -0700 Subject: [PATCH 075/250] docs(sla): address doc-review consensus (cycle 31) Point hosts at the console maintenance window, and keep CLI/REST for SLA service-credit review. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- host/sla-offers.mdx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index f0fbd458..904ef5a1 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -263,7 +263,7 @@ Below is the complete mapping of which endpoints each permission category contro | --- | --- | --- | | List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA**, then **LIST** | | SLA backtester | `machine_read` | Console SLA preview | -| Schedule / cancel maintenance | `machine_write` | None (CLI/REST only) | +| Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances). SLA service-credit review still uses [CLI/REST](/host/sla-offers#scheduled-maintenance). | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | | Verify the listing in search | `misc` | **Host → Machines** (no API key) | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 561a3785..75b2ca5e 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -23,7 +23,7 @@ Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and | Goal | Start here | | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | -| Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer). Planned downtime during active rentals still needs [CLI/REST schedule maint](#scheduled-maintenance) — no in-console scheduler. | +| Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer). Warn renters from the console ([Set a maintenance window](/host/set-maintenance-window)) or with [CLI/REST schedule maint](#scheduled-maintenance). SLA service-credit review uses the CLI/REST path. | | Enable or update SLA via API | [Before you enable SLA](#before-you-enable-sla) → [API (for automation)](#api-for-automation) | | I list with CLI only (no SLA flags yet) | **Set Pricing → SLA** + **LIST** in the console, or REST `PUT /api/v0/machines/create_asks/` — SLA flags are **not** in `vastai list machine` yet | | Monitor settlement after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | @@ -41,7 +41,7 @@ Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and ## Before you enable SLA -If you expect downtime during active rentals, install the [Vast CLI](/cli/hello-world) (or plan to use the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)) **before** enabling SLA. Planned SLA maintenance must be scheduled at least 24 hours ahead via CLI or REST — there is no in-console maintenance scheduler today. +If you expect downtime during active rentals, warn renters before you enable an SLA. The console path is [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances). For SLA service-credit review, also schedule at least 24 hours ahead with the [CLI](/host/cli/schedule-maint) or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint). A service credit is not guaranteed. **Pre-flight checklist (before tuning reliability commitment and confidence):** From 30c08e7cb6a7ddab62fac9042f83102fb34dc368 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Wed, 30 Sep 2026 14:52:56 -0700 Subject: [PATCH 076/250] docs(sla): address doc-review consensus (cycle 32) Describe one maintenance path for notifications, and say a service credit is not guaranteed. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- host/hosting-overview.mdx | 6 +++--- host/sla-offers.mdx | 12 ++++++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 904ef5a1..5d5ae5b2 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -263,7 +263,7 @@ Below is the complete mapping of which endpoints each permission category contro | --- | --- | --- | | List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA**, then **LIST** | | SLA backtester | `machine_read` | Console SLA preview | -| Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances). SLA service-credit review still uses [CLI/REST](/host/sla-offers#scheduled-maintenance). | +| Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | | Verify the listing in search | `misc` | **Host → Machines** (no API key) | diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 4f969fcf..3c57e677 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -243,7 +243,7 @@ You can then look at your [instance tab](https://cloud.vast.ai/instances/) to ma ## Maintenance -**Prerequisite:** Planned maintenance during active SLA rentals requires the [Vast CLI](/cli/hello-world) or REST — there is no in-console scheduler. Install the CLI before you enable SLA — see [Before you enable SLA](/host/sla-offers#before-you-enable-sla). +**Prerequisite:** Notify renters from the console ([Set a maintenance window](/host/set-maintenance-window): **Host → Machines → Settings → Machine Maintenances**) or with the CLI/REST. Use one path per window. For SLA service-credit review, follow [Scheduled maintenance](/host/sla-offers#scheduled-maintenance) (at least 24 hours' notice). A service credit is not guaranteed. Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. @@ -252,7 +252,7 @@ Unlisting the offer prevents new rentals but does not end existing ones. If you Use these paths in order: 1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. -2. **Planned SLA maintenance (active renters):** If SLA is enabled, use [`vastai schedule maint`](/host/cli/schedule-maint) with a start time at least 24 hours in the future. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance) for credit eligibility. +2. **Planned SLA maintenance (active renters):** If SLA is enabled, notify renters at least 24 hours ahead from the console ([Set a maintenance window](/host/set-maintenance-window)) or with [`vastai schedule maint`](/host/cli/schedule-maint). Use one path per window. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance) for credit eligibility. A service credit is not guaranteed. 3. **Emergency or unplanned downtime:** Use [`vastai schedule maint`](/host/cli/schedule-maint) immediately to notify renters. The full service-credit amount that can be owed may apply. The same `schedule maint` command supports planned and emergency notifications; advance notice and duration determine SLA credit eligibility. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. @@ -304,7 +304,7 @@ No, there is not an established process for hosts to message clients on Vast. A drop in reliability does not by itself cost you your verification. What does is an active error. A machine stays de-verified while it has one, and is verified again once the error clears. -Restarting during an active rental does cost you reliability. Schedule a maintenance window first to keep the penalty smaller and recover sooner. +Restarting during an active rental does cost you reliability. Schedule a maintenance window first to keep the penalty smaller and recover sooner. That advice is about your marketplace reliability score. For SLA settlement, follow [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). A service credit is not guaranteed. See [Understanding Verification](/host/understanding-verification). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 75b2ca5e..ea0e297d 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -23,7 +23,7 @@ Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and | Goal | Start here | | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | -| Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer). Warn renters from the console ([Set a maintenance window](/host/set-maintenance-window)) or with [CLI/REST schedule maint](#scheduled-maintenance). SLA service-credit review uses the CLI/REST path. | +| Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer). For downtime, use the console ([Set a maintenance window](/host/set-maintenance-window)) or [CLI/REST](#scheduled-maintenance). Use one path per window. | | Enable or update SLA via API | [Before you enable SLA](#before-you-enable-sla) → [API (for automation)](#api-for-automation) | | I list with CLI only (no SLA flags yet) | **Set Pricing → SLA** + **LIST** in the console, or REST `PUT /api/v0/machines/create_asks/` — SLA flags are **not** in `vastai list machine` yet | | Monitor settlement after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | @@ -32,7 +32,7 @@ Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and 1. Complete [host setup](https://cloud.vast.ai/host/setup/) and list your machine. 2. Test on a [separate client account](/host/hosting-overview#testing-your-own-machine) (billed like any rental). -3. Install the [CLI](/cli/hello-world) (required for SLA maintenance scheduling). +3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. 6. Enable SLA listing and verify in search (`machine_id=` filter). @@ -41,7 +41,7 @@ Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and ## Before you enable SLA -If you expect downtime during active rentals, warn renters before you enable an SLA. The console path is [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances). For SLA service-credit review, also schedule at least 24 hours ahead with the [CLI](/host/cli/schedule-maint) or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint). A service credit is not guaranteed. +If you expect downtime during active rentals, notify renters before you take the machine down. Use either the console ([Set a maintenance window](/host/set-maintenance-window)) or the CLI/REST ([`vastai schedule maint`](/host/cli/schedule-maint)). Use one path per window. For SLA service-credit review, follow [Scheduled maintenance](#scheduled-maintenance): at least 24 hours' notice. A service credit is not guaranteed. **Pre-flight checklist (before tuning reliability commitment and confidence):** @@ -507,7 +507,11 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi ### Scheduled maintenance -**Planned SLA maintenance (may earn a service credit):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for service-credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. A service credit is not guaranteed. Renters should check **Instances** for status. Credited maintenance is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. Credit eligibility is evaluated on a case-by-case basis. + +Notify renters in the console ([Set a maintenance window](/host/set-maintenance-window)) or with CLI/REST. After you schedule from the CLI or API, confirm the window under **Host → Machines → Settings → Machine Maintenances**. Do not schedule the same downtime twice. SLA service-credit review looks for at least 24 hours of notice. A service credit is not guaranteed. + + +**Planned SLA maintenance (renters may qualify for a service credit — not guaranteed):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for service-credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. Renters should check **Instances** for status. Credited maintenance is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. Credit eligibility is evaluated on a case-by-case basis. **CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** Schedule maintenance **sequentially** across a fleet. On HTTP 429, wait and retry with backoff (for example, `sleep 2` between machines). See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). From 95cf98d1c94a667637be8cd719eb96a47863383e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 1 Oct 2026 11:22:35 -0700 Subject: [PATCH 077/250] docs(sla): address doc-review consensus (cycle 33) Put the SLA key recipes above the endpoint catalog, and accept a template without a redundant image. Co-authored-by: Cursor --- api-reference/openapi.yaml | 11 +- .../openapi/yaml/create_instance.yaml | 7 +- api-reference/permissions.mdx | 130 ++++++++---------- guides/instances/choosing/sla-coverage.mdx | 4 +- host/sla-offers.mdx | 8 ++ 5 files changed, 84 insertions(+), 76 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 5076aa9e..bcc50509 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1611,8 +1611,15 @@ paths: application/json: schema: type: object - required: - - image + description: 'Send `image`, `template_hash_id`, or both. When both are + set, the request `image` overrides the template image. + + ' + anyOf: + - required: + - image + - required: + - template_hash_id properties: image: type: string diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index f5baedc0..4bc462fe 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -43,8 +43,11 @@ paths: application/json: schema: type: object - required: - - image + description: | + Send `image`, `template_hash_id`, or both. When both are set, the request `image` overrides the template image. + anyOf: + - required: [image] + - required: [template_hash_id] properties: image: type: string diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 5d5ae5b2..b5a7e072 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -78,18 +78,66 @@ You can create scoped keys using: ### SLA workflows (scoped keys) -**Console-only users** do not need a scoped API key to rent or list with an SLA. These recipes are for REST and CLI automation. +**Console-only users** do not need a scoped API key to rent or list with an SLA. Copy only the JSON in this section. You do not need the endpoint lists later on this page. -| Role | Recipe | -| --- | --- | -| Renter automating search, rent, and verify | [Client SLA recipe](#client-sla-scoped-key-recipe) | -| Host automating list, backtest, and earnings | [Host SLA recipe](#host-sla-scoped-key-recipe) | + + +**Renter — search and REST rent.** Skip this JSON if you rent in the web console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. + +- **Search:** `misc` is the category for `POST /api/v0/bundles/` and CLI `search offers`. There is no search-only permission. `misc` also covers other routes, such as serverless. Use a dedicated key if this automation should not include those routes. +- **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. +- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. + +```json +{ + "api": { + "misc": {}, + "instance_write": {}, + "instance_read": {} + } +} +``` + +This is the minimum for search, REST rent, and verification. Add `user_read` if the flow loads templates or account profile data, and `user_write` if it creates SSH keys or templates. + +| Task | Category | Console fallback | +| --- | --- | --- | +| Search SLA offers | `misc` | **Search** | +| Rent with an SLA | `instance_write` | Console **RENT** | +| Verify `target_reliability` | `instance_read` | **Instances** | + +**Service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. + + +OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not use that endpoint alone to reconcile SLA credits. + -**Renters (clients):** Open the [client SLA recipe](#client-sla-scoped-key-recipe) for the JSON and task table. Use `misc` for search, `instance_write` for rent, and `instance_read` for verification. Do not copy the host recipe. You do not need a scoped API key to rent with an SLA in the web console. + -**Hosts (providers):** Use every category in the [host SLA recipe](#host-sla-scoped-key-recipe) (the full task table is under `machine_write`). `machine_write` by itself is not enough. Add `misc` if you verify the listing with search offers. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). Do not copy the client recipe. Skip that JSON if you only use **Set Pricing → SLA** in the console. +**Host — list, backtest, and earnings.** Skip this JSON if you only use **Set Pricing → SLA** in the console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` by itself cannot backtest, list, and read earnings. -On this page, **client** means renter and **provider** means host. +```json +{ + "api": { + "machine_read": {}, + "machine_write": {}, + "billing_read": {}, + "misc": {} + } +} +``` + +`misc` is required for `vastai search offers` / `POST /api/v0/bundles/`. It is broader than search. Omit it if you only check the listing in the console. You cannot limit `misc` to search only. Use a separate key for SLA scripts. + +| Task | Permission | Console fallback | +| --- | --- | --- | +| List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA**, then **LIST** | +| SLA backtester | `machine_read` | Console SLA preview | +| Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | +| Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | +| Verify the listing in search | `misc` | **Host → Machines** (no API key) | + +Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). ## Custom Roles @@ -150,10 +198,7 @@ You can also use **wildcards** in `params` to represent placeholder values, usef ## Endpoint Reference by Category -**Automators:** copy the scoped key for your role before you scan the endpoint lists. Console users: use the [table at the top of this page](#you-are-here-if). - -- Renters: [client SLA scoped-key recipe](#client-sla-scoped-key-recipe) (in **misc** below) -- Hosts: [host SLA scoped-key recipe](#host-sla-scoped-key-recipe) (in **machine_write** below) +**If you use the API or CLI with scoped keys:** copy the JSON from [SLA workflows](#sla-workflows-scoped-keys) before you scan the endpoint lists. Console users: use the [table at the top of this page](#you-are-here-if). Below is the complete mapping of which endpoints each permission category controls. @@ -228,7 +273,7 @@ Below is the complete mapping of which endpoints each permission category contro - [Show Machines](/api-reference/machines/show-machines) - [Show Reports](/api-reference/machines/show-reports) -- [SLA Backtest](/api-reference/host/sla-backtest) — API-only (hosts): replay historical earnings through SLA math. Requires `machine_read`. See [SLA Backtester](/host/sla-backtester). Console hosts should use the **Set Pricing → SLA** preview instead. Host SLA automation also requires `machine_write` and `billing_read`; see the [host SLA recipe](#host-sla-scoped-key-recipe) under `machine_write`. +- [SLA Backtest](/api-reference/host/sla-backtest) — API-only (hosts): replay historical earnings through SLA math. Requires `machine_read`. See [SLA Backtester](/host/sla-backtester). Console hosts should use the **Set Pricing → SLA** preview instead. Host SLA automation also requires `machine_write` and `billing_read`; see the [host SLA recipe](#host-sla-scoped-key-recipe). ### machine\_write @@ -242,32 +287,7 @@ Below is the complete mapping of which endpoints each permission category contro - [Unlist Machine](/api-reference/machines/unlist-machine) - [Unlist Volume](/api-reference/volumes/unlist-volume) - - -**Host only — minimum SLA API key.** Skip this JSON if you only use **Set Pricing → SLA** in the console. Create via [Create API Key](/api-reference/accounts/create-api-key). See [Creating Scoped Keys](#creating-scoped-keys) for the required `api` wrapper. Enable every category in the JSON below. `machine_write` by itself cannot backtest, list, and read earnings. The **`misc`** category is broader than search: it also covers other routes such as serverless groups. You cannot limit `misc` to search only. Use a separate key for SLA scripts. - -```json -{ - "api": { - "machine_read": {}, - "machine_write": {}, - "billing_read": {}, - "misc": {} - } -} -``` - -`misc` is required for `vastai search offers` / `POST /api/v0/bundles/`. Omit it if you only check the listing in the console. - -| Task | Permission | Console fallback | -| --- | --- | --- | -| List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA**, then **LIST** | -| SLA backtester | `machine_read` | Console SLA preview | -| Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | -| Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | -| Verify the listing in search | `misc` | **Host → Machines** (no API key) | - -Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. +Host SLA keys: [Host SLA recipe](#host-sla-scoped-key-recipe). ### misc @@ -282,37 +302,7 @@ Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user - [Search Offers](/api-reference/search/search-offers) - [Search Volumes](/api-reference/volumes/search-volumes) - - -**Client (renter) only — search and REST rent.** You do not need this JSON to rent in the web console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Hosts should use the [host SLA recipe](#host-sla-scoped-key-recipe), not this one. - -- **Search:** `misc` for `POST /api/v0/bundles/` and CLI `search offers`. There is no search-only permission. `misc` also covers other routes, such as serverless. Use a dedicated key if you do not want SLA automation to include those routes. -- **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. -- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. - -```json -{ - "api": { - "misc": {}, - "instance_write": {}, - "instance_read": {} - } -} -``` - -This is the minimum for search, REST rent, and verification. Add `user_read` if the flow loads templates or account profile data, and `user_write` if it creates SSH keys or templates. See the instance-management example under [Creating Scoped Keys](#creating-scoped-keys). - -| Task | Category | Console fallback | -| --- | --- | --- | -| Search SLA offers | `misc` | **Search** | -| Rent with an SLA | `instance_write` | Console **RENT** | -| Verify `target_reliability` | `instance_read` | **Instances** | - -**Service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. - - -OpenAPI documents charge `type` values only; do not use this endpoint alone to reconcile SLA credits. - +Renter SLA keys: [Renter SLA recipe](#client-sla-scoped-key-recipe). ### team\_read diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 49d2653c..404e94ce 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -53,7 +53,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua 1. Open [Search](https://cloud.vast.ai/create/) and set **Reliability target**. Confirm **On-demand** is selected. 2. Confirm the price breakdown shows an **SLA fee** line before you rent. 3. Click **RENT**. An SLA does not apply to interruptible or bid rentals. -4. After rent, open **Instances** and confirm the SLA terms on the instance. +4. After rent, open **Instances**, select the instance, and open **price details**. An **SLA fee** line means the SLA is on. 5. For service credits after downtime, check **Account → Billing**. They are not in the Charges API. Stop here unless you automate. The steps under [In the web console](#in-the-web-console) repeat this list with the same controls. [API automation](#api-automation) is for API keys. @@ -244,7 +244,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ }' ``` -`template_hash_id` is the content hash of a saved template. The template supplies the image, so this example omits `image`. OpenAPI still lists `image` in the schema `required` array, and the field description says `image` is optional when a template is present. If a client rejects the body for a missing `image`, add `"image"` with the template's container image. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). +`template_hash_id` is the content hash of a saved template. The template supplies the image, so this example omits `image`. Send `image` only when you want to override the template image. The request body must include `image`, `template_hash_id`, or both. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index ea0e297d..ac8d37fb 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -511,6 +511,14 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi Notify renters in the console ([Set a maintenance window](/host/set-maintenance-window)) or with CLI/REST. After you schedule from the CLI or API, confirm the window under **Host → Machines → Settings → Machine Maintenances**. Do not schedule the same downtime twice. SLA service-credit review looks for at least 24 hours of notice. A service credit is not guaranteed. +**Console** + +1. Open [Host → Machines](https://cloud.vast.ai/host/machines/), then **Settings** → **Machine Maintenances**. +2. Set a start at least 24 hours ahead and a duration in whole hours. +3. Confirm the window is listed in that table before you take the machine down. + +**Or use CLI/REST below.** A service credit is not guaranteed either way. + **Planned SLA maintenance (renters may qualify for a service credit — not guaranteed):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for service-credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. Renters should check **Instances** for status. Credited maintenance is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. Credit eligibility is evaluated on a case-by-case basis. **CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** Schedule maintenance **sequentially** across a fleet. On HTTP 429, wait and retry with backoff (for example, `sleep 2` between machines). See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). From 758b0dd413e6a07310cdad4e2f3e168a6e71c93b Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 1 Oct 2026 11:26:43 -0700 Subject: [PATCH 078/250] docs(sla): address doc-review consensus (cycle 34) Clarify template rent and storage matching, and use host/renter wording. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b5a7e072..ed8c8de1 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -11,7 +11,7 @@ Every API key has a set of permissions that control which endpoints it can acces | --- | --- | --- | | Rent with an SLA in the **web console** | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) | No | | List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) | No | -| Automate search, rent, or a host listing | [Client SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | +| Automate search, rent, or a host listing | [Renter SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | On this page, **client** means renter and **provider** means host. Console users do not need **Endpoint Reference by Category** unless they are scoping a key for automation. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index daef7866..549488db 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -153,7 +153,7 @@ vastai search offers 'cpu_arch=arm64' | `inet_down_cost` | float | internet download bandwidth cost in $/GB | | `inet_up` | float | internet upload speed in Mb/s | | `inet_up_cost` | float | internet upload bandwidth cost in $/GB | -| `machine_id` | int | Host machine ID (provider hardware). Use it to find offers from a specific host machine — not the offer/ask `id` and not your rental contract ID (`new_contract`) | +| `machine_id` | int | Host machine ID (the physical machine backing the offer). Use it to find offers from a specific host machine — not the offer/ask `id` and not your rental contract ID (`new_contract`) | | `min_bid` | float | current minimum bid price in $/hr for interruptible | | `num_gpus` | int | number of GPUs | | `pci_gen` | float | PCIE generation | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 404e94ce..0e25375b 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -54,7 +54,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua 2. Confirm the price breakdown shows an **SLA fee** line before you rent. 3. Click **RENT**. An SLA does not apply to interruptible or bid rentals. 4. After rent, open **Instances**, select the instance, and open **price details**. An **SLA fee** line means the SLA is on. -5. For service credits after downtime, check **Account → Billing**. They are not in the Charges API. +5. For service credits after downtime, open **Account → Billing** and look for SLA credit line items after UTC settlement. They are not in the Charges API. Stop here unless you automate. The steps under [In the web console](#in-the-web-console) repeat this list with the same controls. [API automation](#api-automation) is for API keys. @@ -244,7 +244,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ }' ``` -`template_hash_id` is the content hash of a saved template. The template supplies the image, so this example omits `image`. Send `image` only when you want to override the template image. The request body must include `image`, `template_hash_id`, or both. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). +`template_hash_id` is the content hash of a saved template. Include `template_hash_id` to rent from the template. Add `image` only when you want to override the template image. A request needs at least one of those fields. A template rent can send `template_hash_id` alone. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). @@ -271,7 +271,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ | REST search (`POST /api/v0/bundles/`) | 8 GB | `allocated_storage` | GB | | CLI (`vastai search offers`) | 5 GiB | `--storage` | GiB | -**Match disk size when comparing prices.** Defaults differ by channel. When chaining CLI search → REST rent, use the **same integer** on both sides (for example `--storage 50` then `"disk": 50`) — the platform treats that number identically even though REST fields are labeled GB and CLI help says GiB. REST create-instance `disk` must be ≥ **8** when you pass it; do not assume the CLI default of 5 is rentable via REST. +**Match disk size when comparing prices.** Defaults differ by channel. When you rent with REST after a CLI search, pass the same number you searched with (for example `--storage 50` then `"disk": 50`). REST create-instance `disk` must be ≥ **8** when you pass it. The CLI search default of 5 is below that REST minimum. CLI help labels `--storage` as GiB and REST labels `disk` as GB. Confirm the rent price still matches the quote, or rent can fail with `invalid_price`. ## What happens after you rent From 45999970731462d62578659c8b86cbbc7bf3e1bf Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 1 Oct 2026 11:31:44 -0700 Subject: [PATCH 079/250] docs(sla): address doc-review consensus (cycle 35) Look up a new rental by contract id, and show the REST shape for SLA search filters. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 ++ cli/reference/search-offers.mdx | 4 +++- guides/instances/choosing/sla-coverage.mdx | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index ed8c8de1..b1898ff1 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -204,6 +204,8 @@ Below is the complete mapping of which endpoints each permission category contro ### instance\_read +SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#client-sla-scoped-key-recipe). + - [Show Instance](/api-reference/instances/show-instance) - [Show Instances](/api-reference/instances/show-instances) - [Show Logs](/api-reference/instances/show-logs) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 549488db..e52a89d7 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -173,7 +173,9 @@ vastai search offers 'cpu_arch=arm64' | `vms_enabled` | bool | is the machine a VM instance | -SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console or REST create-instance flow documented in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour` — see [SLA → Finding SLA offers](/guides/instances/choosing/sla-coverage#finding-sla-offers). If the CLI warns that an SLA search field is unrecognized, upgrade the CLI and check that the results still match the filters you set. +SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console or REST create-instance flow documented in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. + +The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": {"eq": 0.95}`. In that example `allocated_storage` is a number, not an operator object. If the CLI warns that an SLA search field is unrecognized, upgrade the CLI and check that the results still match the filters you set. ## Global Options diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 0e25375b..b83f9c71 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -216,7 +216,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -**2. Rent** the chosen offer. Use `offers[].id` (or `ask_contract_id`) from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Do not use `bundle_id`. Save `new_contract` from the rent response, then find that contract while paging `GET /api/v1/instances/` and read `target_reliability` and `instance.slaPremiumPerHour` on that row. Pass the **same** reliability target you searched with: +**2. Rent** the chosen offer. Use `offers[].id` (or `ask_contract_id`) from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Do not use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: ```bash curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ @@ -248,7 +248,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). -**3. Verify** via `GET /api/v1/instances/` or `vastai show instances-v1 --raw`: confirm `target_reliability > 0`. For running instances, check `instance.slaPremiumPerHour`; search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. +**3. Verify.** Save `new_contract` from the rent response. Look up that contract with `GET /api/v1/instances/?select_filters={"id":{"eq":NEW_CONTRACT}}`. OpenAPI lists `id` as a filterable column. Or use `vastai show instances-v1 --raw`. Confirm `target_reliability` and `instance.slaPremiumPerHour` on that row. Search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. If the filter returns no row, page with `after_token` until you find `new_contract`. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). The server default `limit` can be as low as **5** (maximum **25**). - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. From 9856d40b70555afafab9f470378e52f615c534d4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 1 Oct 2026 11:36:48 -0700 Subject: [PATCH 080/250] docs(sla): address doc-review consensus (cycle 36) Warn that CLI rent does not turn on an SLA, and make the instance lookup safe to paste. Co-authored-by: Cursor --- api-reference/openapi.yaml | 2 +- api-reference/openapi/yaml/search_offers.yaml | 216 +++++++++--------- api-reference/permissions.mdx | 2 +- guides/instances/choosing/find-and-rent.mdx | 4 + guides/instances/choosing/sla-coverage.mdx | 11 +- 5 files changed, 124 insertions(+), 111 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index bcc50509..ef318844 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6907,7 +6907,7 @@ paths: additionalProperties: true example: offers: - id: 12345678 + - id: 12345678 ask_contract_id: 12345678 bundle_id: 987654321 bundled_results: null diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index 66a9efc4..d8e97ec6 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -306,114 +306,114 @@ paths: additionalProperties: true example: offers: - id: 12345678 - ask_contract_id: 12345678 - bundle_id: 987654321 - bundled_results: null - bw_nvlink: 0 - compute_cap: 900 - cpu_arch: "amd64" - cpu_cores: 64 - cpu_cores_effective: 32 - cpu_ghz: 2.99 - cpu_name: "QuantumX 128-Core Processor" - cpu_ram: 65536 - credit_discount_max: 0.15 - cuda_max_good: 11.2 - direct_port_count: 42 - disk_bw: 1234.5 - disk_name: "HYPERDISK 8TB" - disk_space: 2048.5 - dlperf: 222.22 - dlperf_per_dphtotal: 333.33 - dph_base: 0.123456 - dph_total: 0.234567 - driver_version: "999.99.99" - driver_vers: 999999999 - duration: 1234567.89 - end_date: 1893456000 - external: null - flops_per_dphtotal: 444.44 - geolocation: "Atlantis, AT" - geolocode: 42424242 - gpu_arch: "nvidia" - gpu_display_active: false - gpu_frac: 0.75 - gpu_ids: [1111, 2222] - gpu_lanes: 16 - gpu_mem_bw: 888.8 - gpu_name: "Imaginary RTX 9999" - gpu_ram: 24576 - gpu_total_ram: 49152 - gpu_max_power: 450 - gpu_max_temp: 42 - has_avx: 1 - host_id: 55555 - hosting_type: 0 - hostname: null - inet_down: 9876.5 - inet_down_cost: 0.00123 - inet_up: 8765.4 - inet_up_cost: 0.00456 - is_bid: false - logo: "/static/logos/fake_logo.png" - machine_id: 88888 - min_bid: 0.111111 - mobo_name: "FANTASY-MOBO-2025" - num_gpus: 4 - os_version: "42.42" - pci_gen: 6 - pcie_bw: 99.9 - public_ipaddr: "203.0.113.42" - reliability: 0.9999 - reliability_mult: 0.8888 - rentable: true - rented: false - score: 1234.5678 - start_date: 1893450000.5 - static_ip: true - storage_cost: 0.987654 - storage_total_cost: 0.123456 - total_flops: 999.99 - verification: "verified" - vericode: 1 - vram_costperhour: 0.009876 - webpage: null - vms_enabled: false - expected_reliability: 0.99 - is_vm_deverified: false - resource_type: "gpu" - cluster_id: null - avail_vol_ask_id: 333333 - avail_vol_dph: 0.000321 - avail_vol_size: 4096 - nw_disk_min_bw: null - nw_disk_max_bw: null - nw_disk_avg_bw: null - rn: 1 - dph_total_adj: 0.345678 - reliability2: 0.9999 - discount_rate: 0.05 - discounted_hourly: 0.01 - discounted_dph_total: 0.224567 - search: - gpuCostPerHour: 0.123456 - diskHour: 0.123456 - slaPremiumPerHour: 0.008 - totalHour: 0.234567 - discountTotalHour: 0.01 - discountedTotalPerHour: 0.224567 - instance: - gpuCostPerHour: 0.01 - diskHour: 0.02 - slaPremiumPerHour: 0.008 - totalHour: 0.03 - discountTotalHour: 0.001 - discountedTotalPerHour: 0.029 - time_remaining: "" - time_remaining_isbid: "" - internet_up_cost_per_tb: 1.23 - internet_down_cost_per_tb: 4.56 + - id: 12345678 + ask_contract_id: 12345678 + bundle_id: 987654321 + bundled_results: null + bw_nvlink: 0 + compute_cap: 900 + cpu_arch: "amd64" + cpu_cores: 64 + cpu_cores_effective: 32 + cpu_ghz: 2.99 + cpu_name: "QuantumX 128-Core Processor" + cpu_ram: 65536 + credit_discount_max: 0.15 + cuda_max_good: 11.2 + direct_port_count: 42 + disk_bw: 1234.5 + disk_name: "HYPERDISK 8TB" + disk_space: 2048.5 + dlperf: 222.22 + dlperf_per_dphtotal: 333.33 + dph_base: 0.123456 + dph_total: 0.234567 + driver_version: "999.99.99" + driver_vers: 999999999 + duration: 1234567.89 + end_date: 1893456000 + external: null + flops_per_dphtotal: 444.44 + geolocation: "Atlantis, AT" + geolocode: 42424242 + gpu_arch: "nvidia" + gpu_display_active: false + gpu_frac: 0.75 + gpu_ids: [1111, 2222] + gpu_lanes: 16 + gpu_mem_bw: 888.8 + gpu_name: "Imaginary RTX 9999" + gpu_ram: 24576 + gpu_total_ram: 49152 + gpu_max_power: 450 + gpu_max_temp: 42 + has_avx: 1 + host_id: 55555 + hosting_type: 0 + hostname: null + inet_down: 9876.5 + inet_down_cost: 0.00123 + inet_up: 8765.4 + inet_up_cost: 0.00456 + is_bid: false + logo: "/static/logos/fake_logo.png" + machine_id: 88888 + min_bid: 0.111111 + mobo_name: "FANTASY-MOBO-2025" + num_gpus: 4 + os_version: "42.42" + pci_gen: 6 + pcie_bw: 99.9 + public_ipaddr: "203.0.113.42" + reliability: 0.9999 + reliability_mult: 0.8888 + rentable: true + rented: false + score: 1234.5678 + start_date: 1893450000.5 + static_ip: true + storage_cost: 0.987654 + storage_total_cost: 0.123456 + total_flops: 999.99 + verification: "verified" + vericode: 1 + vram_costperhour: 0.009876 + webpage: null + vms_enabled: false + expected_reliability: 0.99 + is_vm_deverified: false + resource_type: "gpu" + cluster_id: null + avail_vol_ask_id: 333333 + avail_vol_dph: 0.000321 + avail_vol_size: 4096 + nw_disk_min_bw: null + nw_disk_max_bw: null + nw_disk_avg_bw: null + rn: 1 + dph_total_adj: 0.345678 + reliability2: 0.9999 + discount_rate: 0.05 + discounted_hourly: 0.01 + discounted_dph_total: 0.224567 + search: + gpuCostPerHour: 0.123456 + diskHour: 0.123456 + slaPremiumPerHour: 0.008 + totalHour: 0.234567 + discountTotalHour: 0.01 + discountedTotalPerHour: 0.224567 + instance: + gpuCostPerHour: 0.01 + diskHour: 0.02 + slaPremiumPerHour: 0.008 + totalHour: 0.03 + discountTotalHour: 0.001 + discountedTotalPerHour: 0.029 + time_remaining: "" + time_remaining_isbid: "" + internet_up_cost_per_tb: 1.23 + internet_down_cost_per_tb: 4.56 '400': description: Bad request - invalid query parameters content: diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b1898ff1..d607822b 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -114,7 +114,7 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us -**Host — list, backtest, and earnings.** Skip this JSON if you only use **Set Pricing → SLA** in the console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` by itself cannot backtest, list, and read earnings. +**Host — list, backtest, and earnings.** Skip this JSON if you only use **Set Pricing → SLA** in the console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. ```json { diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index ea9a6e76..dfd4e003 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -60,6 +60,10 @@ All stats shown are the portion of the total machine rented. - Rental Option: RENT button - **SLA (optional):** On-demand offers may include an optional SLA. Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). + +Search can quote an SLA. The SLA starts only when you set **Reliability target** in the web console (and see an **SLA fee** line) or send `target_reliability` on REST `PUT /api/v0/asks/{id}/`. `vastai create instance` does not turn an SLA on. See [Create instance](/cli/reference/create-instance). + + ## Instance Disk Size The storage slider is both a search filter and a parameter input which determines the storage allocation size — size it correctly before you create an instance. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b83f9c71..792cf54c 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -248,7 +248,16 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). -**3. Verify.** Save `new_contract` from the rent response. Look up that contract with `GET /api/v1/instances/?select_filters={"id":{"eq":NEW_CONTRACT}}`. OpenAPI lists `id` as a filterable column. Or use `vastai show instances-v1 --raw`. Confirm `target_reliability` and `instance.slaPremiumPerHour` on that row. Search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. If the filter returns no row, page with `after_token` until you find `new_contract`. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). +**3. Verify.** Save `new_contract` from the rent response. Look that contract up with URL-encoded `select_filters` (`id` is a filterable column): + +```bash +curl -G "https://console.vast.ai/api/v1/instances/" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + --data-urlencode 'select_filters={"id":{"eq":NEW_CONTRACT}}' \ + --data-urlencode "limit=25" +``` + +Replace `NEW_CONTRACT` with the id from the rent response. Confirm `target_reliability` and `instance.slaPremiumPerHour` on that row. Search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, page with `after_token`. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). The server default `limit` can be as low as **5** (maximum **25**). - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. From 8fc19a1e8d4f884c716e6a63a15ab76f644aded8 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 1 Oct 2026 11:41:43 -0700 Subject: [PATCH 081/250] docs(sla): address doc-review consensus (cycle 37) Point instance_read at the v1 instances API for SLA field checks. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index d607822b..4c5bdd95 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -207,7 +207,7 @@ Below is the complete mapping of which endpoints each permission category contro SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#client-sla-scoped-key-recipe). - [Show Instance](/api-reference/instances/show-instance) -- [Show Instances](/api-reference/instances/show-instances) +- [Show Instances](/api-reference/instances/show-instances) — this page is `GET /api/v1/instances/`. For SLA fields (`target_reliability`, `instance.slaPremiumPerHour`), use that API or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). Do not use `vastai show instances` for SLA checks. - [Show Logs](/api-reference/instances/show-logs) - [Show SSH Keys](/api-reference/instances/show-ssh-keys) - [Show Volumes](/api-reference/volumes/list-volumes) From 41a6284ae05983313bd5d9888e38f0d0644d0678 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 1 Oct 2026 11:45:06 -0700 Subject: [PATCH 082/250] docs(sla): address doc-review consensus (cycle 38) Separate console users from the SLA key recipes on the permissions page. Co-authored-by: Cursor --- api-reference/permissions.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 4c5bdd95..bb37b043 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -11,9 +11,9 @@ Every API key has a set of permissions that control which endpoints it can acces | --- | --- | --- | | Rent with an SLA in the **web console** | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) | No | | List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) | No | -| Automate search, rent, or a host listing | [Renter SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | +| Automate search, rent, or host listing | [Renter SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | -On this page, **client** means renter and **provider** means host. Console users do not need **Endpoint Reference by Category** unless they are scoping a key for automation. +On this page, **renter** means client and **host** means provider. API names may still say client or provider. Console users do not need **Endpoint Reference by Category** unless they are scoping a key for automation. For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). @@ -78,7 +78,9 @@ You can create scoped keys using: ### SLA workflows (scoped keys) -**Console-only users** do not need a scoped API key to rent or list with an SLA. Copy only the JSON in this section. You do not need the endpoint lists later on this page. +**For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. + +**Console-only users:** You do not need a scoped API key to rent or list with an SLA. Use the table at the top of this page, then stop. From 66746cc77965ac217b45f94cfce18948ad67dc26 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 1 Oct 2026 11:50:01 -0700 Subject: [PATCH 083/250] docs(sla): address doc-review consensus (cycle 39) Tell renters to use a dedicated search key, and to match disk size across console, CLI, and REST. Co-authored-by: Cursor --- api-reference/permissions.mdx | 3 ++- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index bb37b043..edae5017 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -86,7 +86,8 @@ You can create scoped keys using: **Renter — search and REST rent.** Skip this JSON if you rent in the web console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -- **Search:** `misc` is the category for `POST /api/v0/bundles/` and CLI `search offers`. There is no search-only permission. `misc` also covers other routes, such as serverless. Use a dedicated key if this automation should not include those routes. +- Create a **dedicated** key for this workflow. `misc` is required for search and also covers other routes, such as serverless. Do not reuse a full-access key. +- **Search:** `misc` is the category for `POST /api/v0/bundles/` and CLI `search offers`. There is no search-only permission. - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. - **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index dfd4e003..9227c32d 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -70,7 +70,7 @@ The storage slider is both a search filter and a parameter input which determine When the instance is created, the disk size is set and cannot be modified. Estimate how much disk you need, then move the slider to that size. The default disk size in the console is 10GB. Hosts charge for disk allocation even when the instance is stopped. -If you compare prices across the console, CLI, and REST, match disk size first — defaults differ by channel. See [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation). +If you compare prices across the console, CLI, and REST, match disk size first. Defaults differ: console 10 GB, REST search 8 GB, CLI search 5 GiB. See [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation). ![Diskspace](/images/find-and-rent-diskspace.webp) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 792cf54c..868c796a 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -129,6 +129,8 @@ Searching with a **reliability target of 95%** on an offer where the host's **re 4. Before you click **RENT**, confirm the price breakdown shows an **SLA fee** line. No SLA fee line means that rental has no SLA. 5. Rent as usual. Your target is locked at rent time. +The console disk default is 10 GB. REST search defaults to 8 GB and CLI search to 5 GiB. If you mix those channels, match the same number or the rent price can fail with `invalid_price`. The full table is in [API automation](#api-automation). + CLI and API examples below use the same filters. ### Search filters From 4bd0437fde940bedbadd3e3863175a6b20b15561 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 1 Oct 2026 11:55:42 -0700 Subject: [PATCH 084/250] docs(sla): address doc-review consensus (cycle 40) Fill empty create-instance parameter notes, and state that an SLA does not apply to interruptible bids. Co-authored-by: Cursor --- sdk/python/reference/create-instance.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index c6a4c9d3..095dc873 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -52,7 +52,7 @@ VastAI.create_instance( - docker container image to launch + Docker container image to launch. Pass `image`, `template_hash`, or both. A template can supply the image. @@ -64,7 +64,7 @@ VastAI.create_instance( - + On-demand price in $/hour when you set a price on the rental. An SLA rental is on-demand. Do not set `price` together with `bid_price`. @@ -72,7 +72,7 @@ VastAI.create_instance( - + Extra Docker create options, passed through as a string. @@ -116,7 +116,7 @@ VastAI.create_instance( - + Launch mode. Other fields on this page use values such as `ssh` and `jupyter`. @@ -124,11 +124,11 @@ VastAI.create_instance( - + Optional volume to attach when the instance is created. See the CLI flags `--create-volume` and `--link-volume`. - (OPTIONAL) create an INTERRUPTIBLE instance with per machine bid price in $/hour + (OPTIONAL) create an INTERRUPTIBLE instance with per machine bid price in $/hour. An SLA does not apply to interruptible rentals. From fd3445c9802f491b4275fe116e8975456ef09bca Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:27:24 -0700 Subject: [PATCH 085/250] docs(sla): address doc-review consensus (cycle 41) Warn that v0 show-instance is not for SLA checks, and that SLA credits are not in Charges or Invoices. Co-authored-by: Cursor --- api-reference/permissions.mdx | 6 ++++-- guides/instances/choosing/sla-coverage.mdx | 8 ++++---- host/sla-offers.mdx | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index edae5017..fbc78779 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -5,6 +5,8 @@ sidebarTitle: "Permissions" Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. + + ## You are here if… | If you… | Start here | API key needed? | @@ -109,7 +111,7 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if | Rent with an SLA | `instance_write` | Console **RENT** | | Verify `target_reliability` | `instance_read` | **Instances** | -**Service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) does not yet include SLA settlement line items; `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. +**Service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) and Invoices API (`GET /api/v1/invoices/`) do not include SLA settlement line items; charge `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not use that endpoint alone to reconcile SLA credits. @@ -209,7 +211,7 @@ Below is the complete mapping of which endpoints each permission category contro SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#client-sla-scoped-key-recipe). -- [Show Instance](/api-reference/instances/show-instance) +- [Show Instance](/api-reference/instances/show-instance) — not for SLA verification. That path is `GET /api/v0/instances/{id}/` and does not return SLA fields. Use [Show Instances](/api-reference/instances/show-instances) (`GET /api/v1/instances/`) or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). - [Show Instances](/api-reference/instances/show-instances) — this page is `GET /api/v1/instances/`. For SLA fields (`target_reliability`, `instance.slaPremiumPerHour`), use that API or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). Do not use `vastai show instances` for SLA checks. - [Show Logs](/api-reference/instances/show-logs) - [Show SSH Keys](/api-reference/instances/show-ssh-keys) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 868c796a..0bbd59ab 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -45,8 +45,8 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | | I use only the CLI today | Search can quote an SLA. Enabling it requires the console or [API automation](#api-automation). `vastai create instance` does not set `target_reliability`. | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | -| Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in the console billing UI today — not in `GET /api/v0/charges/` or client webhooks | -| View service credits | **Console only** today (**Account → Billing**). The Charges API does not include SLA credit lines, and there are no SLA credit webhooks. | +| Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in **Account → Billing** today — not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | +| View service credits | **Console only** today (**Account → Billing**). The Charges and Invoices APIs do not include SLA credit lines, and there are no SLA credit webhooks. | **Console checklist (web only).** You do not need an API key. @@ -187,7 +187,7 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d | Search / quote an SLA | Yes | Yes (`POST /api/v0/bundles/`) | | Enable an SLA at rent | Yes | Yes (`target_reliability` on `PUT /api/v0/asks/{id}/`) | | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | -| SLA service credits | **Account → Billing** | Not in `GET /api/v0/charges/` and not in client webhooks | +| SLA service credits | **Account → Billing** | Not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | **Prerequisites:** You should be comfortable with REST, an API key, and JSON. Otherwise stay on [In the web console](#in-the-web-console). Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. @@ -397,7 +397,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta **Console:** After UTC settlement, open **Account → Billing** and look for SLA credit line items alongside compute charges. -**API:** Prefer **Account → Billing** for service credit reconciliation. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. +**API:** Prefer **Account → Billing** for service credit reconciliation. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. `GET /api/v1/invoices/` covers payment transactions (top-ups, transfers, payouts), not SLA service-credit line items. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. ## Related documentation diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index ac8d37fb..925113c8 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -35,7 +35,7 @@ Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. -6. Enable SLA listing and verify in search (`machine_id=` filter). +6. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. Verify in search (`machine_id=` filter). 7. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental. ## Before you enable SLA From 3b23cf8673dab712212a4a0ea793996258aeab6a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:31:21 -0700 Subject: [PATCH 086/250] docs(sla): address doc-review consensus (cycle 42) Align SDK price with interruptible bids, and gate API automation behind an API key. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 6 +++++- sdk/python/reference/create-instance.mdx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 0bbd59ab..04036dce 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -182,6 +182,10 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d **Console renters can stop after [In the web console](#in-the-web-console).** This section is for API keys. + +**Before you use this section:** Create an API key under **Account → API Keys**, and be comfortable with REST and JSON. For a scoped key, see [Authentication](/api-reference/authentication) and the [renter SLA recipe](/api-reference/permissions#client-sla-scoped-key-recipe). If you prefer the UI, use [In the web console](#in-the-web-console) instead. + + | Capability | Console | REST | | --- | --- | --- | | Search / quote an SLA | Yes | Yes (`POST /api/v0/bundles/`) | @@ -189,7 +193,7 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | | SLA service credits | **Account → Billing** | Not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | -**Prerequisites:** You should be comfortable with REST, an API key, and JSON. Otherwise stay on [In the web console](#in-the-web-console). Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. +**Prerequisites:** Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. CLI and SDK `create instance` cannot set `target_reliability`. After a CLI/SDK search, complete the rental in the console (set Reliability target, then confirm an SLA charge line) or use the REST example below. If the instance has no SLA charge line, you do not have an SLA. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 095dc873..005c02c4 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -64,7 +64,7 @@ VastAI.create_instance( - On-demand price in $/hour when you set a price on the rental. An SLA rental is on-demand. Do not set `price` together with `bid_price`. + Bid price per machine in $/hour for interruptible rentals only. For on-demand rentals—including SLA via REST `target_reliability`—omit both `price` and `bid_price`. From 9cd832886fc27bc961e175c052dc9000e8bc6f8c Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:35:16 -0700 Subject: [PATCH 087/250] docs(sla): address doc-review consensus (cycle 43) Point console renters to one checklist, spell out the misc key blast radius, and defer SLA credit rules to sla-offers. Co-authored-by: Cursor --- api-reference/permissions.mdx | 8 +++++--- guides/instances/choosing/sla-coverage.mdx | 14 +++++--------- host/hosting-overview.mdx | 8 ++++---- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index fbc78779..c28af8a9 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -82,14 +82,16 @@ You can create scoped keys using: **For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. +**In plain language:** Search with `has_sla` → rent with `target_reliability` → confirm an SLA fee on the instance → view service credits in **Account → Billing**. Console deep links: [renter](/guides/instances/choosing/sla-coverage#in-the-web-console), [host](/host/sla-offers#web-console). + **Console-only users:** You do not need a scoped API key to rent or list with an SLA. Use the table at the top of this page, then stop. **Renter — search and REST rent.** Skip this JSON if you rent in the web console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -- Create a **dedicated** key for this workflow. `misc` is required for search and also covers other routes, such as serverless. Do not reuse a full-access key. -- **Search:** `misc` is the category for `POST /api/v0/bundles/` and CLI `search offers`. There is no search-only permission. +- Create a **dedicated** key for this workflow only. `misc` is required for search (`POST /api/v0/bundles/`, CLI `search offers`) but is broader than bundles—it also covers other routes such as serverless. Constraints cannot limit `misc` to search only today. Do not reuse a full-access key. +- **Search:** `misc` (no search-only permission exists). - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. - **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. @@ -119,7 +121,7 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us -**Host — list, backtest, and earnings.** Skip this JSON if you only use **Set Pricing → SLA** in the console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. +**Host — list, backtest, and earnings.** If you only list and monitor in the console (**Set Pricing → SLA**), you do not need this JSON. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. ```json { diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 04036dce..673f94dc 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -48,20 +48,16 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua | Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in **Account → Billing** today — not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | | View service credits | **Console only** today (**Account → Billing**). The Charges and Invoices APIs do not include SLA credit lines, and there are no SLA credit webhooks. | -**Console checklist (web only).** You do not need an API key. +**Console renters (web only).** You do not need an API key. Follow the five steps in [In the web console](#in-the-web-console), then stop unless you automate. [API automation](#api-automation) is for API keys. -1. Open [Search](https://cloud.vast.ai/create/) and set **Reliability target**. Confirm **On-demand** is selected. -2. Confirm the price breakdown shows an **SLA fee** line before you rent. -3. Click **RENT**. An SLA does not apply to interruptible or bid rentals. -4. After rent, open **Instances**, select the instance, and open **price details**. An **SLA fee** line means the SLA is on. -5. For service credits after downtime, open **Account → Billing** and look for SLA credit line items after UTC settlement. They are not in the Charges API. - -Stop here unless you automate. The steps under [In the web console](#in-the-web-console) repeat this list with the same controls. [API automation](#api-automation) is for API keys. + +Match disk or storage size across search and rent. Defaults differ by channel (console 10 GB, REST search 8 GB, CLI search 5 GiB). Mixing channels can cause `invalid_price`. See the table under [API automation](#api-automation) before you automate. + **CLI-only workflow** 1. Search with SLA filters (`has_sla`, `target_reliability`) to see the quoted SLA fee. -2. The SLA starts only after you rent in the console (set **Reliability target**, then confirm the **SLA fee** in the price breakdown) or with REST `PUT /api/v0/asks/{id}/` and `target_reliability`. +2. You must finish rent in the console (set **Reliability target**, confirm an **SLA fee** line) or with REST `PUT /api/v0/asks/{id}/` and `target_reliability`. If **Instances → price details** has no SLA fee line, you do not have an SLA. 3. `vastai create instance` by itself does not turn on an SLA. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 3c57e677..d08288af 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -243,7 +243,7 @@ You can then look at your [instance tab](https://cloud.vast.ai/instances/) to ma ## Maintenance -**Prerequisite:** Notify renters from the console ([Set a maintenance window](/host/set-maintenance-window): **Host → Machines → Settings → Machine Maintenances**) or with the CLI/REST. Use one path per window. For SLA service-credit review, follow [Scheduled maintenance](/host/sla-offers#scheduled-maintenance) (at least 24 hours' notice). A service credit is not guaranteed. +**Prerequisite:** Notify renters from the console ([Set a maintenance window](/host/set-maintenance-window)) or with the CLI/REST. Use one path per window. Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. @@ -252,10 +252,10 @@ Unlisting the offer prevents new rentals but does not end existing ones. If you Use these paths in order: 1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. -2. **Planned SLA maintenance (active renters):** If SLA is enabled, notify renters at least 24 hours ahead from the console ([Set a maintenance window](/host/set-maintenance-window)) or with [`vastai schedule maint`](/host/cli/schedule-maint). Use one path per window. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance) for credit eligibility. A service credit is not guaranteed. -3. **Emergency or unplanned downtime:** Use [`vastai schedule maint`](/host/cli/schedule-maint) immediately to notify renters. The full service-credit amount that can be owed may apply. +2. **Planned downtime with active renters:** Schedule at least 24 hours ahead from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). +3. **Emergency or unplanned downtime:** Notify renters immediately with [`vastai schedule maint`](/host/cli/schedule-maint). -The same `schedule maint` command supports planned and emergency notifications; advance notice and duration determine SLA credit eligibility. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. +For SLA service-credit rules, notice windows, and confirmation steps, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). A service credit is not guaranteed. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. ## Uninstalling From 3eec4adceb2b384581b6ad65bd2db670f74c53e0 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:39:29 -0700 Subject: [PATCH 088/250] docs(sla): address doc-review consensus (cycle 44) Stop console readers before the endpoint catalog, and lead the backtester with a path table. Co-authored-by: Cursor --- api-reference/permissions.mdx | 6 ++++- guides/instances/choosing/sla-coverage.mdx | 6 +++++ host/sla-backtester.mdx | 28 ++++++++++------------ host/sla-offers.mdx | 6 +++++ 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index c28af8a9..60abe0cc 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -90,7 +90,7 @@ You can create scoped keys using: **Renter — search and REST rent.** Skip this JSON if you rent in the web console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -- Create a **dedicated** key for this workflow only. `misc` is required for search (`POST /api/v0/bundles/`, CLI `search offers`) but is broader than bundles—it also covers other routes such as serverless. Constraints cannot limit `misc` to search only today. Do not reuse a full-access key. +- Create a **dedicated** key for this workflow only. `misc` is required for search (`POST /api/v0/bundles/`, CLI `search offers`) but is broader than bundles—it also covers other routes such as serverless. Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. Console rent needs no API key. - **Search:** `misc` (no search-only permission exists). - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. - **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. @@ -205,6 +205,10 @@ You can also use **wildcards** in `params` to represent placeholder values, usef ## Endpoint Reference by Category + +If you rent or list with an SLA only in the web console, you do not need API keys or the endpoint lists below. Stop after the [renter SLA recipe](#client-sla-scoped-key-recipe) or [host SLA recipe](#host-sla-scoped-key-recipe). Hosts who automate fleet scripts can stop after the host recipe unless they need unrelated permissions. + + **If you use the API or CLI with scoped keys:** copy the JSON from [SLA workflows](#sla-workflows-scoped-keys) before you scan the endpoint lists. Console users: use the [table at the top of this page](#you-are-here-if). Below is the complete mapping of which endpoints each permission category controls. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 673f94dc..23515024 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -39,6 +39,10 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua ## Choose your path + +Search can quote SLA pricing. An SLA starts only when you set a reliability target at rent (console or REST `PUT /api/v0/asks/{id}/`) — not via `vastai create instance` or SDK `create_instance()`. Instance billing continues during outages; SLA service credits settle separately in **Account → Billing**. + + | Goal | Start here | | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | @@ -266,6 +270,8 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm `target_relia **Billing reconciliation (console):** confirming the SLA does not show service credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. +**Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/` (`target_reliability`, `instance.slaPremiumPerHour`). + | Symptom | Typical response | What to do | | --- | --- | --- | | Target on a non-SLA offer | HTTP 400 `invalid_args` | Search with `has_sla=true`; confirm `expected_reliability` | diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 59fe4c89..09760a6f 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -1,33 +1,31 @@ --- title: "SLA Earnings Backtester" -description: "Replay your machine's historical earnings through SLA math to preview SLA charges and credits before listing." +description: "Host-only. Replay your machine's historical earnings through SLA math to preview SLA charges and credits before listing." "canonical": "/host/sla-backtester" --- The **SLA (Service Level Agreement) earnings backtester** is for hosts. Renters should use [SLA](/guides/instances/choosing/sla-coverage). -It lets you answer a practical question before you list: *if clients had rented with reliability target **`r`** and I offered an SLA at confidence **`p`**, how would that have affected my earnings on this machine over the last few months?* +How much could SLA settlement cost given your reliability commitment and confidence? Use the console preview on [SLA Offers](/host/sla-offers#web-console), or the API backtester on this page. + +## Choose your path + +| If you want to… | Use | +| --- | --- | +| Preview SLA before your first listing | Web console (**Set Pricing → SLA** on the machine page) — no API key needed | +| Simulate historical earnings for one machine | This page's single-machine `curl` example | +| Review many machines at once | [Fleet workflow](#fleet-workflow) below (advanced; Linux/macOS + `jq`) | **Console hosts:** use **Set Pricing → SLA** in the web console to preview SLA charges — you do not need this API. -**API hosts:** this endpoint replays historical earnings through SLA math to estimate SLA charges and worst-day credit risk before listing. (**`r`** = reliability level used as both reliability commitment and target in the simulation; **`p`** = host confidence — both defined in [Query parameters](#query-parameters) below.) +**API hosts:** this endpoint replays historical earnings through SLA math to estimate SLA charges and worst-day credit risk before listing. Query parameters `r` (reliability commitment and simulated target) and `p` (host confidence) are defined under [Query parameters](#query-parameters). It replays your machine's **real historical compute earnings and reliability** through the same SLA settlement math used in production, then compares the simulated result to what you actually earned from SLA (if anything). -See [Choose your path](#choose-your-path) below. - **Don't want to use the API?** The backtester is optional. Use the web console SLA preview and the [economics walkthrough](/host/sla-offers#economics-walkthrough) on SLA Offers to evaluate SLA before listing. The backtester is for hosts who want historical replay via the API. -## Choose your path - -| If you want to… | Use | -| --- | --- | -| Preview SLA before your first listing | Web console (**Set Pricing → SLA** on the machine page) — no API key needed | -| Simulate historical earnings for one machine | This page's single-machine `curl` example | -| Review many machines at once | [Fleet workflow](#fleet-workflow) below (advanced; Linux/macOS + `jq`) | - ## When to use it Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. @@ -290,9 +288,9 @@ For missing or invalid API keys and permission denials (`machine_read`), see [Au ## Fleet workflow -Optional. Skip this section unless you automate many machines. Console hosts can use **Set Pricing → SLA** and a single request instead of the loop below. +**Console-only hosts: stop here** — use **Set Pricing → SLA** on [SLA Offers](/host/sla-offers#web-console) instead of this loop. -This section is for hosts automating fleet review. Console-only hosts can run the baseline `curl` once per machine instead. +Optional. Skip this section unless you automate many machines. Console hosts can use **Set Pricing → SLA** and a single request instead of the loop below. ```bash export VAST_API_KEY="YOUR_API_KEY" diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 925113c8..3ec9c546 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -20,6 +20,10 @@ SLA settlement is **asymmetric by design**: when reliability is strong relative Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. + +Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong). Skip [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) and API automation unless you manage many machines with scripts. + + | Goal | Start here | | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | @@ -618,6 +622,8 @@ Positive `sla_earn` = net SLA charge you kept that period; negative = net credit This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll at most about once every two seconds per IP; back off on HTTP 429. +**Automation pattern:** There is no host webhook for SLA settlement. Poll `machine-earnings` with `last_days=1` and `machid`, alert on `per_machine[].sla_earn` thresholds, and call machines sequentially with backoff on 429. Do not use `per_day[].sla_earn` for a single machine. + When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. From 3cfc9fb6cf5816f3b1cfcaed8e6507b82b3b2a3b Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:43:11 -0700 Subject: [PATCH 089/250] docs(sla): address doc-review consensus (cycle 45) Lead console renters to the web steps first, and put maintenance before go-live on the host checklist. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 8 +++----- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 23515024..bb2ddaf1 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -33,14 +33,12 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua **SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via the **REST API**, pass `target_reliability` on **create-instance** (`PUT /api/v0/asks/{id}/`). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. - -`vastai search offers` only quotes SLA pricing. `target_reliability` is **not yet** available on the published `vastai create instance` CLI or Python SDK `create_instance()`. Use the **web console** or **REST** create-instance to enable the SLA (see [Finding SLA offers](#finding-sla-offers)). - +**Web console only (start here):** Set **Reliability target** on search, confirm an **SLA fee** (or **SLA charge**) line in the price breakdown, rent on-demand, then verify under **Instances** and credits under **Account → Billing**. Full steps: [In the web console](#in-the-web-console). CLI and API paths are under [Choose your path](#choose-your-path). ## Choose your path -Search can quote SLA pricing. An SLA starts only when you set a reliability target at rent (console or REST `PUT /api/v0/asks/{id}/`) — not via `vastai create instance` or SDK `create_instance()`. Instance billing continues during outages; SLA service credits settle separately in **Account → Billing**. +Search quotes an SLA; rent enables it (console or REST). `vastai create instance` and SDK `create_instance()` do not. Billing continues during outages; service credits settle later in **Account → Billing**. Details: [Finding SLA offers](#finding-sla-offers). | Goal | Start here | @@ -401,7 +399,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing** and look for SLA credit line items alongside compute charges. +**Console:** After UTC settlement, open **Account → Billing** and look for **service credit** or SLA credit line items (wording can vary)—not in the instance price panel. Credits are not available via the Charges API, invoices, or billing exports today. **API:** Prefer **Account → Billing** for service credit reconciliation. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. `GET /api/v1/invoices/` covers payment transactions (top-ups, transfers, payouts), not SLA service-credit line items. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index d08288af..693c09ee 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -40,7 +40,7 @@ Clients have high expectations coming from AWS or GCP. As a host, plan to offer ## Offers and Rental Contracts -Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or REST `create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). +Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or `PUT /api/v0/machines/create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). The main offer parameters include: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 3ec9c546..1260ecab 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -39,8 +39,8 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. -6. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. Verify in search (`machine_id=` filter). -7. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental. +6. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). +7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. Verify in search (`machine_id=` filter). ## Before you enable SLA From c69455c442c81b6de5f1ff4867a92794cea3e908 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:46:24 -0700 Subject: [PATCH 090/250] docs(sla): address doc-review consensus (cycle 46) Steer console SLA users off the permissions encyclopedia and reserve scoped-key recipes for automation. Co-authored-by: Cursor --- api-reference/permissions.mdx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 60abe0cc..44b13a0b 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -11,11 +11,11 @@ Every API key has a set of permissions that control which endpoints it can acces | If you… | Start here | API key needed? | | --- | --- | --- | -| Rent with an SLA in the **web console** | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) | No | -| List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) | No | +| Rent with an SLA in the **web console** | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) — then leave this page | No | +| List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) — then leave this page | No | | Automate search, rent, or host listing | [Renter SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | -On this page, **renter** means client and **host** means provider. API names may still say client or provider. Console users do not need **Endpoint Reference by Category** unless they are scoping a key for automation. +On this page, **renter** means client and **host** means provider. API names may still say client or provider. Console SLA users: follow the links above and stop—do not create API keys or read **Endpoint Reference by Category**. For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). @@ -80,11 +80,13 @@ You can create scoped keys using: ### SLA workflows (scoped keys) -**For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. + +You do not need a scoped API key to use SLA in the web console. Hosts: configure SLA under **Set Pricing → SLA** ([SLA Offers → Web console](/host/sla-offers#web-console)). Renters: use **RENT** with a reliability target ([SLA coverage → In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console)). Use the recipes below only for automation (backtester, `create_asks`, earnings, `search offers`, REST rent). + -**In plain language:** Search with `has_sla` → rent with `target_reliability` → confirm an SLA fee on the instance → view service credits in **Account → Billing**. Console deep links: [renter](/guides/instances/choosing/sla-coverage#in-the-web-console), [host](/host/sla-offers#web-console). +**For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. -**Console-only users:** You do not need a scoped API key to rent or list with an SLA. Use the table at the top of this page, then stop. +**If you automate:** Search with `has_sla` → rent with `target_reliability` → confirm an SLA fee on the instance → view service credits in **Account → Billing**. Console deep links: [renter](/guides/instances/choosing/sla-coverage#in-the-web-console), [host](/host/sla-offers#web-console). @@ -206,7 +208,7 @@ You can also use **wildcards** in `params` to represent placeholder values, usef ## Endpoint Reference by Category -If you rent or list with an SLA only in the web console, you do not need API keys or the endpoint lists below. Stop after the [renter SLA recipe](#client-sla-scoped-key-recipe) or [host SLA recipe](#host-sla-scoped-key-recipe). Hosts who automate fleet scripts can stop after the host recipe unless they need unrelated permissions. +If you rent or list with an SLA only in the web console, you do not need API keys or the endpoint lists below. Stop after the [renter SLA recipe](#client-sla-scoped-key-recipe) or [host SLA recipe](#host-sla-scoped-key-recipe). Hosts who automate listing or earnings can stop after the host recipe unless they need unrelated permissions. **If you use the API or CLI with scoped keys:** copy the JSON from [SLA workflows](#sla-workflows-scoped-keys) before you scan the endpoint lists. Console users: use the [table at the top of this page](#you-are-here-if). From 1f45e699276bdb81ab0c4ef2e292ce583b8682ce Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:50:00 -0700 Subject: [PATCH 091/250] docs(sla): address doc-review consensus (cycle 47) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Block the CLI search→create SLA trap and point verification at the v1 instances path. Co-authored-by: Cursor --- api-reference/permissions.mdx | 6 +++++- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 4 ++++ guides/instances/choosing/sla-coverage.mdx | 13 ++++++++----- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 44b13a0b..57954d86 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -97,6 +97,10 @@ You do not need a scoped API key to use SLA in the web console. Hosts: configure - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. - **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. + +**Common mistake:** `vastai show instances` (v0) and the v0 Show Instance schema do not include SLA fields. Verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. + + ```json { "api": { @@ -219,7 +223,7 @@ Below is the complete mapping of which endpoints each permission category contro SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#client-sla-scoped-key-recipe). -- [Show Instance](/api-reference/instances/show-instance) — not for SLA verification. That path is `GET /api/v0/instances/{id}/` and does not return SLA fields. Use [Show Instances](/api-reference/instances/show-instances) (`GET /api/v1/instances/`) or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). +- [Show Instance](/api-reference/instances/show-instance) — not for SLA verification. That path is `GET /api/v0/instances/{id}/` and does not return SLA fields. Use [Show Instances](/api-reference/instances/show-instances) (`GET /api/v1/instances/`) or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). **Common mistake:** `vastai show instances` (v0) also omits SLA fields. - [Show Instances](/api-reference/instances/show-instances) — this page is `GET /api/v1/instances/`. For SLA fields (`target_reliability`, `instance.slaPremiumPerHour`), use that API or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). Do not use `vastai show instances` for SLA checks. - [Show Logs](/api-reference/instances/show-logs) - [Show SSH Keys](/api-reference/instances/show-ssh-keys) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 680cf94d..931251d9 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create instance" Create a new instance -**SLA:** This command cannot set `target_reliability`. Searching only quotes an SLA. If you searched with `--storage N`, pass `--disk N` here (search defaults to 5 GiB; this command defaults to 10 GB). See [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation). +**SLA:** Search only quotes SLA pricing; it does not enable an SLA at rent time. This command cannot set `target_reliability`—use the web console **RENT** flow or REST `PUT /api/v0/asks/{id}/`. If you searched with `--storage N`, pass `--disk N` here (search defaults to 5 GiB; this command defaults to 10 GB). See [SLA → Finding SLA offers](/guides/instances/choosing/sla-coverage#finding-sla-offers). ## Usage diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index e52a89d7..d3867274 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -94,7 +94,11 @@ vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=Fal # SLA search quote (enable the SLA at rent via console/REST — see SLA) # Always set --storage explicitly when comparing dph_total (CLI default 5 GiB ≠ REST 8 GB). vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total +``` + +**Next step for SLA:** Do not use `vastai create instance` to enable SLA. After search, rent with the web console **RENT** flow or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +```bash # datacenter GPUs with minimum compute capability and TFLOPs vastai search offers 'compute_cap > 610 total_flops > 5 datacenter=True' diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index bb2ddaf1..47c02a41 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -50,7 +50,7 @@ Search quotes an SLA; rent enables it (console or REST). `vastai create instance | Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in **Account → Billing** today — not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | | View service credits | **Console only** today (**Account → Billing**). The Charges and Invoices APIs do not include SLA credit lines, and there are no SLA credit webhooks. | -**Console renters (web only).** You do not need an API key. Follow the five steps in [In the web console](#in-the-web-console), then stop unless you automate. [API automation](#api-automation) is for API keys. +**Console renters (web only).** You do not need an API key. Follow the steps in [In the web console](#in-the-web-console), then stop unless you automate. [API automation](#api-automation) is for API keys. Match disk or storage size across search and rent. Defaults differ by channel (console 10 GB, REST search 8 GB, CLI search 5 GiB). Mixing channels can cause `invalid_price`. See the table under [API automation](#api-automation) before you automate. @@ -125,9 +125,8 @@ Searching with a **reliability target of 95%** on an offer where the host's **re 2. In Search filters (left filter bar), set **Reliability target** to your desired reliability target — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. 3. Optionally narrow results with an SLA-enabled / `has_sla` filter if shown. Filtering listings is **not** the same as enabling the SLA. 4. Before you click **RENT**, confirm the price breakdown shows an **SLA fee** line. No SLA fee line means that rental has no SLA. -5. Rent as usual. Your target is locked at rent time. - -The console disk default is 10 GB. REST search defaults to 8 GB and CLI search to 5 GiB. If you mix those channels, match the same number or the rent price can fail with `invalid_price`. The full table is in [API automation](#api-automation). +5. **Disk before RENT:** Set instance disk on the console slider before **RENT**. If you quoted via CLI or REST, match `allocated_storage` / `disk` to that quote (REST `disk` ≥ 8 when set)—mismatched defaults cause `invalid_price`. See the storage table in [API automation](#api-automation). +6. Rent as usual. Your target is locked at rent time. CLI and API examples below use the same filters. @@ -358,7 +357,11 @@ Production settlement uses the multi-window reliability blend described above, n ### API integrators -Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. (CLI can **read** these fields via `vastai show instances-v1 --raw`; enabling SLA still requires console or REST — see [Finding SLA offers](#finding-sla-offers).) +Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. + + +**Common mistake:** `vastai show instances` (v0) and `GET /api/v0/instances/{id}/` do not return SLA fields. Verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. Enabling SLA still requires console or REST — see [Finding SLA offers](#finding-sla-offers). +
API integrators: field names and filters From 1fec6e2bcbf30f05595c9c643a45507e25222946 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:54:49 -0700 Subject: [PATCH 092/250] docs(sla): address doc-review consensus (cycle 48) Clarify console stop points, disk quoting, and scoped-key blast radius for SLA automation. Co-authored-by: Cursor --- api-reference/permissions.mdx | 8 +++++++- guides/instances/choosing/sla-coverage.mdx | 22 ++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 57954d86..a6d48aff 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -92,6 +92,8 @@ You do not need a scoped API key to use SLA in the web console. Hosts: configure **Renter — search and REST rent.** Skip this JSON if you rent in the web console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. +**Minimum story:** Search → REST rent with `target_reliability` → verify on v1 instances; SLA credits only in the console. + - Create a **dedicated** key for this workflow only. `misc` is required for search (`POST /api/v0/bundles/`, CLI `search offers`) but is broader than bundles—it also covers other routes such as serverless. Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. Console rent needs no API key. - **Search:** `misc` (no search-only permission exists). - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. @@ -129,6 +131,10 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us **Host — list, backtest, and earnings.** If you only list and monitor in the console (**Set Pricing → SLA**), you do not need this JSON. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. +**Minimum story:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. + +`misc` also enables serverless and other routes—not bundles search alone. Host SLA automation keys are account-wide today for listing and `misc` routes; use dedicated keys, rotation, and monitoring for fleet scripts (machine-ID constraints on `machine_write` are not documented for SLA listing). + ```json { "api": { @@ -140,7 +146,7 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us } ``` -`misc` is required for `vastai search offers` / `POST /api/v0/bundles/`. It is broader than search. Omit it if you only check the listing in the console. You cannot limit `misc` to search only. Use a separate key for SLA scripts. +`misc` is required for `vastai search offers` / `POST /api/v0/bundles/`. Omit it if you only check the listing in the console. You cannot limit `misc` to search only. Use a separate key for SLA scripts. | Task | Permission | Console fallback | | --- | --- | --- | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 47c02a41..4dcbd802 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -45,10 +45,10 @@ Search quotes an SLA; rent enables it (console or REST). `vastai create instance | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | -| I use only the CLI today | Search can quote an SLA. Enabling it requires the console or [API automation](#api-automation). `vastai create instance` does not set `target_reliability`. | +| I use only the CLI today | [CLI search](#finding-sla-offers) → [API automation](#api-automation) to enable SLA at rent | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | -| Automate search → rent → verify | [API automation](#api-automation) (REST). **Billing reconciliation:** service credits appear in **Account → Billing** today — not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | -| View service credits | **Console only** today (**Account → Billing**). The Charges and Invoices APIs do not include SLA credit lines, and there are no SLA credit webhooks. | +| Automate search → rent → verify | [API automation](#api-automation) | +| View service credits | **Account → Billing** (console only today) | **Console renters (web only).** You do not need an API key. Follow the steps in [In the web console](#in-the-web-console), then stop unless you automate. [API automation](#api-automation) is for API keys. @@ -175,10 +175,16 @@ When you search with an SLA target, reserved-instance discounts may not apply to Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `dph_total` to compare total quoted cost. +**Console-only readers:** You can stop after [In the web console](#in-the-web-console). SLA in the browser does not require an API key. For automation, continue to [API automation](#api-automation). + ### API automation **Console renters can stop after [In the web console](#in-the-web-console).** This section is for API keys. + +Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. SLA service credits appear only in the web console billing UI—not in Charges, Invoices, or credit webhooks. + + **Before you use this section:** Create an API key under **Account → API Keys**, and be comfortable with REST and JSON. For a scoped key, see [Authentication](/api-reference/authentication) and the [renter SLA recipe](/api-reference/permissions#client-sla-scoped-key-recipe). If you prefer the UI, use [In the web console](#in-the-web-console) instead. @@ -192,15 +198,13 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d **Prerequisites:** Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. -CLI and SDK `create instance` cannot set `target_reliability`. After a CLI/SDK search, complete the rental in the console (set Reliability target, then confirm an SLA charge line) or use the REST example below. If the instance has no SLA charge line, you do not have an SLA. +For details on CLI/SDK rent limits and billing reconciliation, see [Automation limits (read once)](#api-automation) above. For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Renters set **`target_reliability`** on search and on REST rent. **`sla_r_target`** is a stored field name in some instance filters — do not send it in the rent body. -**Billing reconciliation:** service credits appear in the console billing UI today. They are not included in `GET /api/v0/charges/` and client webhooks for SLA credits are not available — plan manual console reconciliation after UTC settlement (see [FAQ](#where-do-i-see-historical-sla-credits)). - -**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable): +**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Raise `limit` within API bounds when you need more rows. The bundles search body documents **`limit` only**—there is no offset or page token—so one response is the full result set for that query. For safe retry loops on HTTP 429, see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ @@ -285,7 +289,9 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm `target_relia | REST search (`POST /api/v0/bundles/`) | 8 GB | `allocated_storage` | GB | | CLI (`vastai search offers`) | 5 GiB | `--storage` | GiB | -**Match disk size when comparing prices.** Defaults differ by channel. When you rent with REST after a CLI search, pass the same number you searched with (for example `--storage 50` then `"disk": 50`). REST create-instance `disk` must be ≥ **8** when you pass it. The CLI search default of 5 is below that REST minimum. CLI help labels `--storage` as GiB and REST labels `disk` as GB. Confirm the rent price still matches the quote, or rent can fail with `invalid_price`. +**Match disk size when comparing prices.** Defaults differ by channel. When you rent with REST after a CLI search, pass the same number you searched with (for example `--storage 50` then `"disk": 50`). REST create-instance `disk` must be ≥ **8** when you pass it. The CLI search default of 5 is below that REST minimum. CLI help labels `--storage` as GiB and REST labels `disk` as GB. + +**Quoting rule:** Use the same disk number end-to-end for the channel you rent through (console slider, REST `disk` / `allocated_storage`, or CLI `--storage`). If you mix channels, set disk explicitly on every search and rent step. Treat the same integer as one quote across CLI GiB and REST GB labels unless the API returns a mismatch error (`invalid_price`). ## What happens after you rent From 284e5e59d701c3294b4e6904729f9d054f2313cd Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 2 Oct 2026 12:59:20 -0700 Subject: [PATCH 093/250] docs(sla): address doc-review consensus (cycle 49) Fix OpenAPI order schema, clarify host key blast radius, and trim repeated SLA warnings. Co-authored-by: Cursor --- api-reference/openapi.yaml | 4 ++-- api-reference/openapi/yaml/search_offers.yaml | 4 ++-- api-reference/permissions.mdx | 4 +++- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 6 +++--- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index ef318844..124e5824 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6871,8 +6871,8 @@ paths: type: array items: type: string - minItems: 2 - maxItems: 2 + minItems: 2 + maxItems: 2 allocated_storage: type: number description: 'Storage allocation size in GB for the instance. diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index d8e97ec6..d5281d50 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -274,8 +274,8 @@ paths: type: array items: type: string - minItems: 2 - maxItems: 2 + minItems: 2 + maxItems: 2 allocated_storage: type: number description: | diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index a6d48aff..b94bdda6 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -133,7 +133,9 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us **Minimum story:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. -`misc` also enables serverless and other routes—not bundles search alone. Host SLA automation keys are account-wide today for listing and `misc` routes; use dedicated keys, rotation, and monitoring for fleet scripts (machine-ID constraints on `machine_write` are not documented for SLA listing). +`misc` also enables serverless and other routes—not bundles search alone. + +**Host SLA automation keys:** `machine_write` and related host scopes apply account-wide today. Use dedicated keys with rotation and monitoring for fleet jobs; do not assume per-machine key scoping for `create_asks` or maintenance unless documented under [Constraints](#constraints). ```json { diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 931251d9..f838980f 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create instance" Create a new instance -**SLA:** Search only quotes SLA pricing; it does not enable an SLA at rent time. This command cannot set `target_reliability`—use the web console **RENT** flow or REST `PUT /api/v0/asks/{id}/`. If you searched with `--storage N`, pass `--disk N` here (search defaults to 5 GiB; this command defaults to 10 GB). See [SLA → Finding SLA offers](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**SLA:** This command cannot set `target_reliability`. Search → rent with SLA is documented under [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers) (console or REST). Match `--disk` to any `--storage` you used in search. ## Usage diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index d3867274..3e2c3410 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -84,7 +84,7 @@ bool = True | False ## Examples -**Search quotes SLA pricing only.** `vastai create instance` cannot pass `target_reliability` today — use the web console or REST to enable the SLA; see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers). When `target_reliability` is set, prefer `dph_total` (and `--order dph_total`) over `dph` for the all-in price. If you set `--storage N` here, pass `--disk N` on `vastai create instance` (search defaults to 5 GiB; create instance defaults to 10 GB). +**Search quotes SLA pricing only.** Prefer `dph_total` (and `--order dph_total`) when comparing SLA quotes. Match `--storage` to `--disk` if you rent via CLI for non-SLA. To **enable** SLA at rent, see [Next step for SLA](#examples) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 4dcbd802..eb491b88 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -128,7 +128,9 @@ Searching with a **reliability target of 95%** on an offer where the host's **re 5. **Disk before RENT:** Set instance disk on the console slider before **RENT**. If you quoted via CLI or REST, match `allocated_storage` / `disk` to that quote (REST `disk` ≥ 8 when set)—mismatched defaults cause `invalid_price`. See the storage table in [API automation](#api-automation). 6. Rent as usual. Your target is locked at rent time. -CLI and API examples below use the same filters. + +**Console-only:** You can stop here. SLA rental in the web console does not require CLI or API keys. Continue below only if you automate search or rent. + ### Search filters @@ -175,8 +177,6 @@ When you search with an SLA target, reserved-instance discounts may not apply to Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `dph_total` to compare total quoted cost. -**Console-only readers:** You can stop after [In the web console](#in-the-web-console). SLA in the browser does not require an API key. For automation, continue to [API automation](#api-automation). - ### API automation **Console renters can stop after [In the web console](#in-the-web-console).** This section is for API keys. From 23ceb848df97e5a232f40d7cd3c77ad250d0ec02 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:18:16 -0700 Subject: [PATCH 094/250] docs(sla): address doc-review consensus (cycle 50) Clarify misc key scope wording and align price_disk units with host CLI docs. Co-authored-by: Cursor --- api-reference/openapi.yaml | 2 +- api-reference/openapi/yaml/list_machine.yaml | 2 +- api-reference/permissions.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 124e5824..4a87f8fe 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4564,7 +4564,7 @@ paths: price_disk: type: number format: float - description: Price per GB of disk storage + description: Price per GB of disk storage per month (USD/GB/month). price_inetu: type: number format: float diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 960b0f4b..03047865 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -39,7 +39,7 @@ paths: price_disk: type: number format: float - description: Price per GB of disk storage + description: Price per GB of disk storage per month (USD/GB/month). price_inetu: type: number format: float diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b94bdda6..5649cf8f 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -133,7 +133,7 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us **Minimum story:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. -`misc` also enables serverless and other routes—not bundles search alone. +`misc` covers bundle search and other routes (including serverless)—not bundle search only. **Host SLA automation keys:** `machine_write` and related host scopes apply account-wide today. Use dedicated keys with rotation and monitoring for fleet jobs; do not assume per-machine key scoping for `create_asks` or maintenance unless documented under [Constraints](#constraints). From f2e635831c7e76fe50adfe1cb737bd0d49e7479a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:21:14 -0700 Subject: [PATCH 095/250] docs(sla): address doc-review consensus (cycle 51) Rename CLI search-only path and label host create_asks partial updates as not first listings. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 ++ guides/instances/choosing/sla-coverage.mdx | 10 +++++++--- host/sla-offers.mdx | 6 ++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 5649cf8f..e19082ab 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -5,6 +5,8 @@ sidebarTitle: "Permissions" Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. +**Console SLA users:** use the table below—if you rent or host SLA only in the web UI, follow the link out. You do not need API keys for console SLA. + ## You are here if… diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index eb491b88..0c3398e3 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -45,7 +45,7 @@ Search quotes an SLA; rent enables it (console or REST). `vastai create instance | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | | Rent with SLA in the console | [Finding SLA offers → In the web console](#in-the-web-console) | -| I use only the CLI today | [CLI search](#finding-sla-offers) → [API automation](#api-automation) to enable SLA at rent | +| I use the CLI for search | [CLI for search only](#cli-for-search-only) → console or REST to enable SLA at rent | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | | Automate search → rent → verify | [API automation](#api-automation) | | View service credits | **Account → Billing** (console only today) | @@ -56,10 +56,14 @@ Search quotes an SLA; rent enables it (console or REST). `vastai create instance Match disk or storage size across search and rent. Defaults differ by channel (console 10 GB, REST search 8 GB, CLI search 5 GiB). Mixing channels can cause `invalid_price`. See the table under [API automation](#api-automation) before you automate. -**CLI-only workflow** + + +**CLI for search only** + +You cannot complete an SLA rental with `vastai create instance` alone. SLA is enabled at rent time in the web console or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. 1. Search with SLA filters (`has_sla`, `target_reliability`) to see the quoted SLA fee. -2. You must finish rent in the console (set **Reliability target**, confirm an **SLA fee** line) or with REST `PUT /api/v0/asks/{id}/` and `target_reliability`. If **Instances → price details** has no SLA fee line, you do not have an SLA. +2. Finish rent in the console: re-open Search, set **Reliability target** again (CLI filters do not carry over), confirm an **SLA fee** line, then **RENT**—or use REST with `target_reliability`. If **Instances → price details** has no SLA fee line, you do not have an SLA. 3. `vastai create instance` by itself does not turn on an SLA. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1260ecab..04a63ae6 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -260,8 +260,10 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons 4. To enable SLA today, use `PUT /api/v0/machines/create_asks/` or **Set Pricing → SLA** in the console. The listing body field is `machine` (same ID as backtester `machine_id` and earnings `machid`). 5. For the full request/response schema, see [List Machine](/api-reference/machines/list-machine). +#### Update SLA on an existing ask (partial body) + -**Not a first listing.** The curl below adds SLA fields to a machine that already has base pricing. A first `create_asks` must also include `min_chunk` and typical disk and bandwidth prices. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). +**Not a first listing.** The curl below adds SLA fields to a machine that already has base pricing. For a **first publish**, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include at least `min_chunk`, disk/bandwidth prices, and `end_date`) or **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). ```bash @@ -369,7 +371,7 @@ done Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. -**SLA-only update** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep: +**SLA-only update (existing ask only)** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep. Do **not** use this body for a first listing. ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ From 8b0e8eae087cfd1982ea99b94c4650cf1894ebe9 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:25:50 -0700 Subject: [PATCH 096/250] docs(sla): address doc-review consensus (cycle 52) Fix the automation-limits anchor and clarify search vs instance SLA fee fields on verify. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 0c3398e3..76dd9910 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -185,6 +185,8 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d **Console renters can stop after [In the web console](#in-the-web-console).** This section is for API keys. + + Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. SLA service credits appear only in the web console billing UI—not in Charges, Invoices, or credit webhooks. @@ -200,9 +202,9 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | | SLA service credits | **Account → Billing** | Not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | -**Prerequisites:** Happy path: search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. +**Prerequisites (happy path):** Search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. Console users can skip this section. -For details on CLI/SDK rent limits and billing reconciliation, see [Automation limits (read once)](#api-automation) above. +See the [Automation limits](#automation-limits) note in this section before you script search → rent → verify. For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -268,7 +270,7 @@ curl -G "https://console.vast.ai/api/v1/instances/" \ --data-urlencode "limit=25" ``` -Replace `NEW_CONTRACT` with the id from the rent response. Confirm `target_reliability` and `instance.slaPremiumPerHour` on that row. Search-context snapshots use `search.slaPremiumPerHour`. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, page with `after_token`. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). +Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row. For the SLA fee: if the instance is not yet **running**, use `search.slaPremiumPerHour` (search-context pricing); once **running**, also check `instance.slaPremiumPerHour`. A missing `instance.slaPremiumPerHour` before startup is not a failed SLA rent. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, page with `after_token`. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). The server default `limit` can be as low as **5** (maximum **25**). - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. From 5e00aed7c31b84d1b7cbe74b3b176e011d4bb9af Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:29:45 -0700 Subject: [PATCH 097/250] docs(sla): address doc-review consensus (cycle 53) Warn that fleet re-list republishes, document bundles search sharding, and add a console quick start. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 4 +++- guides/instances/choosing/sla-coverage.mdx | 14 ++++++++------ host/sla-offers.mdx | 8 ++++++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 3e2c3410..7e4f1b8a 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -84,7 +84,7 @@ bool = True | False ## Examples -**Search quotes SLA pricing only.** Prefer `dph_total` (and `--order dph_total`) when comparing SLA quotes. Match `--storage` to `--disk` if you rent via CLI for non-SLA. To **enable** SLA at rent, see [Next step for SLA](#examples) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**Search quotes SLA pricing only.** Prefer `dph_total` (and `--order dph_total`) when comparing SLA quotes. Match `--storage` to `--disk` if you rent via CLI for non-SLA. To **enable** SLA at rent, see [Next step for SLA](#next-step-for-sla) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash @@ -96,6 +96,8 @@ vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=Fal vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total ``` + + **Next step for SLA:** Do not use `vastai create instance` to enable SLA. After search, rent with the web console **RENT** flow or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 76dd9910..7e60cd8c 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -33,13 +33,15 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua **SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via the **REST API**, pass `target_reliability` on **create-instance** (`PUT /api/v0/asks/{id}/`). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. -**Web console only (start here):** Set **Reliability target** on search, confirm an **SLA fee** (or **SLA charge**) line in the price breakdown, rent on-demand, then verify under **Instances** and credits under **Account → Billing**. Full steps: [In the web console](#in-the-web-console). CLI and API paths are under [Choose your path](#choose-your-path). +**Console quick start (no API key):** -## Choose your path +1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. +2. Set **Reliability target**, confirm an **SLA fee** line, then **RENT**. +3. Verify under **Instances**; after UTC settlement, check credits in **Account → Billing**. - -Search quotes an SLA; rent enables it (console or REST). `vastai create instance` and SDK `create_instance()` do not. Billing continues during outages; service credits settle later in **Account → Billing**. Details: [Finding SLA offers](#finding-sla-offers). - +Full steps: [In the web console](#in-the-web-console). CLI/API limits for automation are under [API automation](#api-automation). + +## Choose your path | Goal | Start here | | --- | --- | @@ -210,7 +212,7 @@ For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, Renters set **`target_reliability`** on search and on REST rent. **`sla_r_target`** is a stored field name in some instance filters — do not send it in the rent body. -**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Raise `limit` within API bounds when you need more rows. The bundles search body documents **`limit` only**—there is no offset or page token—so one response is the full result set for that query. For safe retry loops on HTTP 429, see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). +**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 04a63ae6..0715c165 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -317,9 +317,13 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge **Console hosts:** skip this section. Enable an SLA with [Web console](#web-console) and check settlement in [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). -This loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only re-publishes machines that already have `sla_r_claim > 0`. +This loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that already have `sla_r_claim > 0`. -`PUT /api/v0/machines/create_asks/` publishes a live listing (same as **LIST**). Only run this loop on machines you intend to list or update. Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. + +`PUT /api/v0/machines/create_asks/` **publishes a live listing** (same as **LIST**). A `sla_r_claim > 0` filter is **not** a listed-status check—running with `DRY_RUN=0` can put intentionally unlisted or paused machines back on the market. Before you apply, confirm each machine is **Listed** (or that you intend to re-list it) on **Host → Machines**. There is no documented `show machines --raw` field for listed vs unlisted in this guide; gate in the console or your own inventory before applying. + + +Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. **Before fleet SLA rollout:** From 45381b5b5ba05c736a3e685e80f3f5e4d70a2ee0 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:33:57 -0700 Subject: [PATCH 098/250] docs(sla): address doc-review consensus (cycle 54) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mark permissions recipes as automation-only and reinforce CLI→console Reliability target at RENT. Co-authored-by: Cursor --- api-reference/permissions.mdx | 10 ++++++++-- cli/reference/search-offers.mdx | 2 ++ guides/instances/choosing/sla-coverage.mdx | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index e19082ab..8bce67dd 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -5,7 +5,7 @@ sidebarTitle: "Permissions" Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. -**Console SLA users:** use the table below—if you rent or host SLA only in the web UI, follow the link out. You do not need API keys for console SLA. +**Audience:** Console SLA (hosts and renters): use the **You are here if…** table and the console routing links—no API key required. Everything under **Automation only** is for scripted search, listing, and earnings. @@ -82,8 +82,12 @@ You can create scoped keys using: ### SLA workflows (scoped keys) +#### Automation only + +Recipes below are for scripted search, listing, backtester, and earnings—not for console-only SLA. + -You do not need a scoped API key to use SLA in the web console. Hosts: configure SLA under **Set Pricing → SLA** ([SLA Offers → Web console](/host/sla-offers#web-console)). Renters: use **RENT** with a reliability target ([SLA coverage → In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console)). Use the recipes below only for automation (backtester, `create_asks`, earnings, `search offers`, REST rent). +You do not need a scoped API key to use SLA in the web console. Hosts: configure SLA under **Set Pricing → SLA** ([SLA Offers → Web console](/host/sla-offers#web-console)). Renters: use **RENT** with a reliability target ([SLA coverage → In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console)). **For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. @@ -162,6 +166,8 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). +**Console-only?** Stop here—[Host SLA offers](/host/sla-offers) · [Renter SLA coverage](/guides/instances/choosing/sla-coverage#in-the-web-console). + ## Custom Roles Custom roles let you assign the same set of permissions to multiple team members. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 7e4f1b8a..fcb6bf8a 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -9,6 +9,8 @@ Search for instance types using custom query Search can quote an SLA. The CLI cannot turn an SLA on when you rent. Use the web console or REST with `target_reliability`. See [SLA](/guides/instances/choosing/sla-coverage). +**SLA-only quick path:** `vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total` — then enable SLA at rent (console **RENT** with **Reliability target**, or REST). See [Next step for SLA](#next-step-for-sla) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). + ## Usage ```bash diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 7e60cd8c..c35912f6 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -39,6 +39,8 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua 2. Set **Reliability target**, confirm an **SLA fee** line, then **RENT**. 3. Verify under **Instances**; after UTC settlement, check credits in **Account → Billing**. +**If you used the CLI to search:** set **Reliability target** again in the web console before you click **RENT**. CLI filters do not carry over. + Full steps: [In the web console](#in-the-web-console). CLI/API limits for automation are under [API automation](#api-automation). ## Choose your path From 5a40f6c96d5e938c3a029d2cc45c2c32a912f3cd Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:38:47 -0700 Subject: [PATCH 099/250] docs(sla): address doc-review consensus (cycle 55) Lead permissions with console routing, clarify sliced-host worst_day_loss limits, and sanitize CLI examples. Co-authored-by: Cursor --- api-reference/permissions.mdx | 26 +++++++++++++++++++------- cli/reference/create-instance.mdx | 14 +++++++------- cli/reference/search-offers.mdx | 6 ++++-- host/sla-backtester.mdx | 1 + host/sla-offers.mdx | 2 +- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 8bce67dd..630edef1 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -3,14 +3,12 @@ title: "Permissions" sidebarTitle: "Permissions" --- -Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. - -**Audience:** Console SLA (hosts and renters): use the **You are here if…** table and the console routing links—no API key required. Everything under **Automation only** is for scripted search, listing, and earnings. - ## You are here if… +**Console SLA: no API key** — use [SLA coverage](/guides/instances/choosing/sla-coverage) (renters) or [SLA Offers](/host/sla-offers) (hosts). + | If you… | Start here | API key needed? | | --- | --- | --- | | Rent with an SLA in the **web console** | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) — then leave this page | No | @@ -19,6 +17,8 @@ Every API key has a set of permissions that control which endpoints it can acces On this page, **renter** means client and **host** means provider. API names may still say client or provider. Console SLA users: follow the links above and stop—do not create API keys or read **Endpoint Reference by Category**. +Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. Everything under **Automation only** is for scripted search, listing, and earnings. + For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). ## Permission Categories @@ -96,7 +96,13 @@ You do not need a scoped API key to use SLA in the web console. Hosts: configure -**Renter — search and REST rent.** Skip this JSON if you rent in the web console. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. +**Renter — search and REST rent.** + + +**Console-only:** You do not need this recipe — use [Rent with SLA (console)](/guides/instances/choosing/sla-coverage#in-the-web-console). + + +Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. **Minimum story:** Search → REST rent with `target_reliability` → verify on v1 instances; SLA credits only in the console. @@ -106,7 +112,7 @@ You do not need a scoped API key to use SLA in the web console. Hosts: configure - **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. -**Common mistake:** `vastai show instances` (v0) and the v0 Show Instance schema do not include SLA fields. Verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. +**Common mistake:** `vastai show instances` (v0) and the v0 Show Instance endpoint do not include SLA fields. Verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. ```json @@ -135,7 +141,13 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us -**Host — list, backtest, and earnings.** If you only list and monitor in the console (**Set Pricing → SLA**), you do not need this JSON. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. +**Host — list, backtest, and earnings.** + + +**Console-only:** You do not need this recipe — use [List with SLA (console)](/host/sla-offers#web-console). + + +If you only list and monitor in the console (**Set Pricing → SLA**), you do not need this JSON. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. **Minimum story:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index f838980f..34bc3dde 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -129,7 +129,7 @@ vastai create instance ID [OPTIONS] [--args ...] ## Description -Performs the same action as pressing the "RENT" button on the website at https://cloud.vast.ai/create/ +Performs the same action as pressing the "RENT" button on the website at https://cloud.vast.ai/create/. Creates an instance from an offer ID (which is returned from "search offers"). Each offer ID can only be used to create one instance. Besides the offer ID, you must pass either `--image` or `--template_hash`. A template supplies the image. `vastai create instance` cannot set `target_reliability`. @@ -142,25 +142,25 @@ For ssh/jupyter launch types, use `--onstart-cmd` to pass in startup script, ins ```bash # create an on-demand instance with the PyTorch (cuDNN Devel) template and 64GB of disk -vastai create instance 384826 --template_hash 661d064bbda1f2a133816b6d55da07c3 --disk 64 +vastai create instance 1000001 --template_hash TEMPLATE_HASH --disk 64 # create an on-demand instance with the pytorch/pytorch image, 40GB of disk, open 8081 udp, direct ssh, set hostname to billybob, and a small onstart script -vastai create instance 6995713 --image pytorch/pytorch --disk 40 --env '-p 8081:8081/udp -h billybob' --ssh --direct --onstart-cmd "env | grep _ >> /etc/environment; echo 'starting up'"; +vastai create instance 1000002 --image pytorch/pytorch --disk 40 --env '-p 8081:8081/udp -h billybob' --ssh --direct --onstart-cmd "env | grep _ >> /etc/environment; echo 'starting up'"; # create an on-demand instance with a private image (use your registry password, not a real secret in docs) -vastai create instance 384827 --image YOUR_REGISTRY/pytorch:latest --login '-u YOUR_USER -p YOUR_PASSWORD docker.io' --jupyter --direct --env '-e TZ=PDT -e XNAME=XX4 -p 22:22 -p 8080:8080' --disk 20 +vastai create instance 1000003 --image YOUR_REGISTRY/pytorch:latest --login '-u YOUR_USER -p YOUR_PASSWORD docker.io' --jupyter --direct --env '-e TZ=PDT -e XNAME=XX4 -p 22:22 -p 8080:8080' --disk 20 # create an on-demand instance with the pytorch/pytorch image, 40GB of disk, override the entrypoint to bash and pass bash a simple command to keep the instance running. (args launch without ssh/jupyter) -vastai create instance 5801802 --image pytorch/pytorch --disk 40 --onstart-cmd 'bash' --args -c 'echo hello; sleep infinity;' +vastai create instance 1000004 --image pytorch/pytorch --disk 40 --onstart-cmd 'bash' --args -c 'echo hello; sleep infinity;' # create an interruptible (spot) instance with the PyTorch (cuDNN Devel) template, 64GB of disk, and a bid price of $0.10/hr -vastai create instance 384826 --template_hash 661d064bbda1f2a133816b6d55da07c3 --disk 64 --bid_price 0.1 +vastai create instance 1000001 --template_hash TEMPLATE_HASH --disk 64 --bid_price 0.1 ``` Return value — JSON with `new_contract`, the rental contract ID for the new instance. Use this value in the console **Instances** list and with `GET /api/v1/instances/` as the instance `id` (`vastai show instances-v1 --raw` for v1 fields). It is not the search offer/ask `id` you passed to create-instance. ```json -{"success": true, "new_contract": 7835610} +{"success": true, "new_contract": 2000001} ``` ## Global Options diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index fcb6bf8a..ec2b25c0 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -11,6 +11,8 @@ Search can quote an SLA. The CLI cannot turn an SLA on when you rent. Use the we **SLA-only quick path:** `vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total` — then enable SLA at rent (console **RENT** with **Reliability target**, or REST). See [Next step for SLA](#next-step-for-sla) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +Console renters: prefer [SLA → In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console). This page assumes CLI usage. + ## Usage ```bash @@ -26,7 +28,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] ## Options - Show 'on-demand', 'reserved', or 'bid'(interruptible) pricing. default: on-demand (alias: `--type`) + Show 'on-demand', 'reserved', or 'bid' (interruptible) pricing. default: on-demand (alias: `--type`) @@ -170,7 +172,7 @@ vastai search offers 'cpu_arch=arm64' | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability commitment on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | -| `target_reliability` | float | reliability target (0–1 exclusive); prices `dph_total` in search only — see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers) to enable the SLA at rent | +| `target_reliability` | float | reliability target greater than 0 and less than 1 (e.g. `0.95` = 95% — console **Reliability target**); prices `dph_total` in search only — see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers) to enable the SLA at rent | | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 09760a6f..14fb60fe 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -58,6 +58,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). - For client-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or search with a realistic `target_reliability`. - For tail risk, trust `worst_day_loss`, not headline `total_sla`. - Timescale mix (`β`) is derived from `r` (weights recent vs longer-term uptime in settlement). Hosts cannot set β via the listing API. +- **Backtester limits:** Multi-renter overlap on one machine may exceed simulated `worst_day_loss`. Pair this output with [SLA and GPU slicing](/host/sla-offers#sla-and-gpu-slicing) when several SLA contracts can run concurrently. ## Before you start diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 0715c165..8826ece9 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -205,7 +205,7 @@ SLA settlement applies per rental contract. If your machine has multiple GPU sli The backtester replays **machine-level** daily earnings (total compute across all active rentals on that machine). `worst_day_loss` in `summary` reflects the worst simulated day for the whole machine in the replay window — not a single GPU slice in isolation. -On sliced machines, a full-machine outage can affect every concurrent SLA rental at once. Use `worst_day_loss` as your primary tail-risk metric for the machine, and sanity-check exposure against how many SLA-covered instances you typically run in parallel. Do **not** multiply `worst_day_loss` by contract count — the backtester already models machine-level compute for the replay window. +If multiple on-demand SLA contracts can be active on one machine at once, a single outage may trigger service credits **per contract**. The backtester’s `worst_day_loss` reflects machine-level replay for one simulated day—it may not equal the sum of worst-case credits across concurrent SLA renters. For sliced hosts, stress-test with your expected concurrent SLA contract count or treat `worst_day_loss` as a **lower bound** until you confirm aggregation with support. Do **not** naively multiply `worst_day_loss` by contract count as a substitute for that check—the backtester already models machine-level compute for the replay window, but live per-contract settlement can still stack differently than one simulated day. ### SLA on extended contracts From 95e3d6da873a7c8ceece19c50ecebf8e7b6aeed1 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:42:02 -0700 Subject: [PATCH 100/250] docs(sla): address doc-review consensus (cycle 56) Put the SLA rent handoff before the CLI search-offers quick path. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index ec2b25c0..2d4d4d9c 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -9,9 +9,11 @@ Search for instance types using custom query Search can quote an SLA. The CLI cannot turn an SLA on when you rent. Use the web console or REST with `target_reliability`. See [SLA](/guides/instances/choosing/sla-coverage). -**SLA-only quick path:** `vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total` — then enable SLA at rent (console **RENT** with **Reliability target**, or REST). See [Next step for SLA](#next-step-for-sla) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**Need SLA?** Search can quote SLA pricing, but SLA is enabled only when you rent—in the web console (**Reliability target** on **RENT**) or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. The CLI and published SDK cannot enable SLA at rent time. If you need SLA, stop after search and follow [Rent with SLA (console)](/guides/instances/choosing/sla-coverage#in-the-web-console) or [API automation](/guides/instances/choosing/sla-coverage#api-automation). Do not run `vastai create instance` expecting SLA. -Console renters: prefer [SLA → In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console). This page assumes CLI usage. +Console renters: prefer [Rent with SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) in the web console. This page assumes CLI usage. + +**CLI search quote (after the note above):** `vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total` — then enable SLA at rent as described above. See [Next step for SLA](#next-step-for-sla). ## Usage From 62efe483ee1c1713973d99e668766deeafc6d48f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:46:31 -0700 Subject: [PATCH 101/250] docs(sla): address doc-review consensus (cycle 57) Narrow host misc keys, shorten search-offers SLA front-matter, and align fleet backtest r with listing claims. Co-authored-by: Cursor --- api-reference/permissions.mdx | 39 +++++++++++++++++++-------------- cli/reference/search-offers.mdx | 11 +++++----- host/sla-backtester.mdx | 12 +++++----- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 630edef1..199b84b7 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -3,6 +3,8 @@ title: "Permissions" sidebarTitle: "Permissions" --- +Console renters and hosts: you do not need this page to use SLA in the web console. Renters: [In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console). Hosts: [Listing an SLA offer (console)](/host/sla-offers#web-console). + ## You are here if… @@ -104,16 +106,12 @@ You do not need a scoped API key to use SLA in the web console. Hosts: configure Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -**Minimum story:** Search → REST rent with `target_reliability` → verify on v1 instances; SLA credits only in the console. +**Workflow summary:** Search → REST rent with `target_reliability` → verify on v1 instances; SLA credits only in the console. -- Create a **dedicated** key for this workflow only. `misc` is required for search (`POST /api/v0/bundles/`, CLI `search offers`) but is broader than bundles—it also covers other routes such as serverless. Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. Console rent needs no API key. -- **Search:** `misc` (no search-only permission exists). +- Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. Console rent needs no API key. +- **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. -- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. On a running instance, the SLA fee is `instance.slaPremiumPerHour`. Search-context fields on that same payload use `search.slaPremiumPerHour`. - - -**Common mistake:** `vastai show instances` (v0) and the v0 Show Instance endpoint do not include SLA fields. Verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. - +- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (v0 `show instances` omits SLA fields). On a running instance, the SLA fee is `instance.slaPremiumPerHour`; before running, use `search.slaPremiumPerHour`. ```json { @@ -147,26 +145,33 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us **Console-only:** You do not need this recipe — use [List with SLA (console)](/host/sla-offers#web-console). -If you only list and monitor in the console (**Set Pricing → SLA**), you do not need this JSON. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. +Console listing and billing checks need no API key. The JSON below is only if you automate search, `create_asks`, backtest, or `machine-earnings`. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. -**Minimum story:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. - -`misc` covers bundle search and other routes (including serverless)—not bundle search only. +**Workflow summary:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. **Host SLA automation keys:** `machine_write` and related host scopes apply account-wide today. Use dedicated keys with rotation and monitoring for fleet jobs; do not assume per-machine key scoping for `create_asks` or maintenance unless documented under [Constraints](#constraints). +**Listing + earnings only** (no search)—prefer this for fleet cron jobs: + ```json { "api": { "machine_read": {}, "machine_write": {}, - "billing_read": {}, - "misc": {} + "billing_read": {} } } ``` -`misc` is required for `vastai search offers` / `POST /api/v0/bundles/`. Omit it if you only check the listing in the console. You cannot limit `misc` to search only. Use a separate key for SLA scripts. +**Verify offers in search** — add `misc` on a **separate**, narrowly scoped key (`misc` also covers serverless and other routes—not search only): + +```json +{ + "api": { + "misc": {} + } +} +``` | Task | Permission | Console fallback | | --- | --- | --- | @@ -174,7 +179,7 @@ If you only list and monitor in the console (**Set Pricing → SLA**), you do no | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | -| Verify the listing in search | `misc` | **Host → Machines** (no API key) | +| Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key) | Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). @@ -251,7 +256,7 @@ Below is the complete mapping of which endpoints each permission category contro SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#client-sla-scoped-key-recipe). -- [Show Instance](/api-reference/instances/show-instance) — not for SLA verification. That path is `GET /api/v0/instances/{id}/` and does not return SLA fields. Use [Show Instances](/api-reference/instances/show-instances) (`GET /api/v1/instances/`) or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). **Common mistake:** `vastai show instances` (v0) also omits SLA fields. +- [Show Instance](/api-reference/instances/show-instance) — v0 path; not for SLA verification (use Show Instances v1 / `show instances-v1` as in the renter recipe). - [Show Instances](/api-reference/instances/show-instances) — this page is `GET /api/v1/instances/`. For SLA fields (`target_reliability`, `instance.slaPremiumPerHour`), use that API or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). Do not use `vastai show instances` for SLA checks. - [Show Logs](/api-reference/instances/show-logs) - [Show SSH Keys](/api-reference/instances/show-ssh-keys) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 2d4d4d9c..6f7b1f32 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -6,14 +6,13 @@ sidebarTitle: "search offers" Search for instance types using custom query -Search can quote an SLA. The CLI cannot turn an SLA on when you rent. Use the web console or REST with `target_reliability`. See [SLA](/guides/instances/choosing/sla-coverage). +Search can quote an SLA. The CLI cannot enable SLA at rent—use the [web console](/guides/instances/choosing/sla-coverage#in-the-web-console) or [API automation](/guides/instances/choosing/sla-coverage#api-automation). Details: [Next step for SLA](#next-step-for-sla). -**Need SLA?** Search can quote SLA pricing, but SLA is enabled only when you rent—in the web console (**Reliability target** on **RENT**) or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. The CLI and published SDK cannot enable SLA at rent time. If you need SLA, stop after search and follow [Rent with SLA (console)](/guides/instances/choosing/sla-coverage#in-the-web-console) or [API automation](/guides/instances/choosing/sla-coverage#api-automation). Do not run `vastai create instance` expecting SLA. +**If you only use the CLI today** -Console renters: prefer [Rent with SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) in the web console. This page assumes CLI usage. - -**CLI search quote (after the note above):** `vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total` — then enable SLA at rent as described above. See [Next step for SLA](#next-step-for-sla). +1. Use `search offers` to compare quotes (SLA filters are optional). +2. To rent with SLA, open the console **RENT** flow with **Reliability target** set, or follow [API automation](/guides/instances/choosing/sla-coverage#api-automation). `vastai create instance` cannot set `target_reliability`. ## Usage @@ -104,7 +103,7 @@ vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability -**Next step for SLA:** Do not use `vastai create instance` to enable SLA. After search, rent with the web console **RENT** flow or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**Next step for SLA:** Search only quotes SLA pricing. Enable SLA at rent in the web console (**Reliability target** on **RENT**) or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. Do not use `vastai create instance` expecting SLA. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash # datacenter GPUs with minimum compute capability and TFLOPs diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 14fb60fe..b2715671 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -298,17 +298,19 @@ export VAST_API_KEY="YOUR_API_KEY" ``` 1. List machine IDs: `vastai show machines -q` (numeric IDs only) or `vastai show machines --raw | jq -r '.machines[].id'`. -2. Run backtests **sequentially** (one machine at a time): +2. Run backtests **sequentially** (one machine at a time). Set `r` to each machine’s **candidate** reliability commitment (the `sla_r_claim` you plan to list)—do not assume a fleet-wide `0.95` if you intend to list at `0.99` or another value: ```bash +# Example uses R=0.99; change per machine or read from your inventory CSV. +R="${R:-0.99}" for id in $(vastai show machines -q); do resp=$(curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=0.95&p=0.6667" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$R&p=0.6667" \ || echo '{"error":"request_failed"}') if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then echo "machine_id=$id error: $(echo "$resp" | jq -r '.error')" else - echo "$resp" | jq '{machine_id: '"$id"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' + echo "$resp" | jq '{machine_id: '"$id"', r: '"$R"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' fi sleep 2 done @@ -316,8 +318,8 @@ done Expect roughly two seconds per machine minimum (`sleep 2` plus request time). For 50 machines, budget at least a few minutes. Run off-peak before a fleet SLA rollout. On `429`, back off per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Parallel requests are not recommended unless you implement backoff. -3. Compare `worst_day_loss` and `total_sla` across machines. -4. Apply `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). +3. Compare `worst_day_loss` and `total_sla` across machines at the same `r` you will list. +4. Apply matching `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). ## When stuck From 5b23798b5ea4c73de03c123e8c8e17cb3f350852 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:51:59 -0700 Subject: [PATCH 102/250] docs(sla): address doc-review consensus (cycle 58) Collapse duplicate console-exit notes on permissions so integrators reach scoped-key recipes faster. Co-authored-by: Cursor --- api-reference/permissions.mdx | 42 +++++++++-------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 199b84b7..2aa5bce0 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -3,13 +3,11 @@ title: "Permissions" sidebarTitle: "Permissions" --- -Console renters and hosts: you do not need this page to use SLA in the web console. Renters: [In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console). Hosts: [Listing an SLA offer (console)](/host/sla-offers#web-console). - ## You are here if… -**Console SLA: no API key** — use [SLA coverage](/guides/instances/choosing/sla-coverage) (renters) or [SLA Offers](/host/sla-offers) (hosts). +Console renters and hosts: you do not need this page to use SLA in the web console. Renters: [In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console). Hosts: [Listing an SLA offer (console)](/host/sla-offers#web-console). | If you… | Start here | API key needed? | | --- | --- | --- | @@ -17,7 +15,7 @@ Console renters and hosts: you do not need this page to use SLA in the web conso | List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) — then leave this page | No | | Automate search, rent, or host listing | [Renter SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | -On this page, **renter** means client and **host** means provider. API names may still say client or provider. Console SLA users: follow the links above and stop—do not create API keys or read **Endpoint Reference by Category**. +On this page, **renter** means client and **host** means provider. API names may still say client or provider. Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. Everything under **Automation only** is for scripted search, listing, and earnings. @@ -43,10 +41,6 @@ Permissions are organized into categories. When you create a scoped API key, you ## Creating Scoped Keys - -Renting or listing with an SLA in the web console does not require a scoped API key. Renters start at [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). Hosts start at [SLA Offers](/host/sla-offers#web-console). - - Define permissions as a JSON object and pass it when creating a key. The top-level key is always `"api"`, containing the categories you want to grant. **Example, Instance management with billing access:** @@ -86,29 +80,23 @@ You can create scoped keys using: #### Automation only -Recipes below are for scripted search, listing, backtester, and earnings—not for console-only SLA. - - -You do not need a scoped API key to use SLA in the web console. Hosts: configure SLA under **Set Pricing → SLA** ([SLA Offers → Web console](/host/sla-offers#web-console)). Renters: use **RENT** with a reliability target ([SLA coverage → In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console)). + +**Console users: stop here.** Recipes below are for scripted search, listing, backtester, and earnings. Console SLA: [renter](/guides/instances/choosing/sla-coverage#in-the-web-console) · [host](/host/sla-offers#web-console). **For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. -**If you automate:** Search with `has_sla` → rent with `target_reliability` → confirm an SLA fee on the instance → view service credits in **Account → Billing**. Console deep links: [renter](/guides/instances/choosing/sla-coverage#in-the-web-console), [host](/host/sla-offers#web-console). +**If you automate:** Search with `has_sla` → rent with `target_reliability` → confirm an SLA fee on the instance → view service credits in **Account → Billing**. **Renter — search and REST rent.** - -**Console-only:** You do not need this recipe — use [Rent with SLA (console)](/guides/instances/choosing/sla-coverage#in-the-web-console). - - Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -**Workflow summary:** Search → REST rent with `target_reliability` → verify on v1 instances; SLA credits only in the console. +**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. SLA credits appear only in the console. -- Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. Console rent needs no API key. +- Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. - **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (v0 `show instances` omits SLA fields). On a running instance, the SLA fee is `instance.slaPremiumPerHour`; before running, use `search.slaPremiumPerHour`. @@ -141,11 +129,7 @@ OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not us **Host — list, backtest, and earnings.** - -**Console-only:** You do not need this recipe — use [List with SLA (console)](/host/sla-offers#web-console). - - -Console listing and billing checks need no API key. The JSON below is only if you automate search, `create_asks`, backtest, or `machine-earnings`. Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. +Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. **Workflow summary:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. @@ -183,8 +167,6 @@ Console listing and billing checks need no API key. The JSON below is only if yo Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). -**Console-only?** Stop here—[Host SLA offers](/host/sla-offers) · [Renter SLA coverage](/guides/instances/choosing/sla-coverage#in-the-web-console). - ## Custom Roles Custom roles let you assign the same set of permissions to multiple team members. @@ -244,11 +226,7 @@ You can also use **wildcards** in `params` to represent placeholder values, usef ## Endpoint Reference by Category - -If you rent or list with an SLA only in the web console, you do not need API keys or the endpoint lists below. Stop after the [renter SLA recipe](#client-sla-scoped-key-recipe) or [host SLA recipe](#host-sla-scoped-key-recipe). Hosts who automate listing or earnings can stop after the host recipe unless they need unrelated permissions. - - -**If you use the API or CLI with scoped keys:** copy the JSON from [SLA workflows](#sla-workflows-scoped-keys) before you scan the endpoint lists. Console users: use the [table at the top of this page](#you-are-here-if). +Copy the JSON from [SLA workflows](#sla-workflows-scoped-keys) before you scan the endpoint lists. Below is the complete mapping of which endpoints each permission category controls. @@ -325,7 +303,7 @@ SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for - [Show Machines](/api-reference/machines/show-machines) - [Show Reports](/api-reference/machines/show-reports) -- [SLA Backtest](/api-reference/host/sla-backtest) — API-only (hosts): replay historical earnings through SLA math. Requires `machine_read`. See [SLA Backtester](/host/sla-backtester). Console hosts should use the **Set Pricing → SLA** preview instead. Host SLA automation also requires `machine_write` and `billing_read`; see the [host SLA recipe](#host-sla-scoped-key-recipe). +- [SLA Backtest](/api-reference/host/sla-backtest) — API-only (hosts): replay historical earnings through SLA math. Requires `machine_read`. See [SLA Backtester](/host/sla-backtester). Host SLA automation also requires `machine_write` and `billing_read`; see the [host SLA recipe](#host-sla-scoped-key-recipe). ### machine\_write From c7e21b999073a4d7be12b377834474dfa439ed86 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 09:56:35 -0700 Subject: [PATCH 103/250] docs(sla): address doc-review consensus (cycle 59) State that machine_write cannot be constrained, lead create_asks with SLA-only bodies, and cut duplicate CLI SLA warnings. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 +++- cli/reference/search-offers.mdx | 1 + guides/instances/choosing/find-and-rent.mdx | 2 +- host/sla-offers.mdx | 15 ++++++++++++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 2aa5bce0..e4e5804b 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -133,7 +133,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do **Workflow summary:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. -**Host SLA automation keys:** `machine_write` and related host scopes apply account-wide today. Use dedicated keys with rotation and monitoring for fleet jobs; do not assume per-machine key scoping for `create_asks` or maintenance unless documented under [Constraints](#constraints). +**Host SLA automation keys:** `machine_write` applies to all machines on the account. You cannot scope `create_asks` or maintenance to a subset of machines via API key constraints today. Use dedicated keys with rotation and monitoring for fleet jobs. **Listing + earnings only** (no search)—prefer this for fleet cron jobs: @@ -218,6 +218,8 @@ Constraints narrow a permission category to specific parameter values. This lets Supported constraint operators: `eq`, `lte`, `gte`. +Host listing (`machine_write` / `create_asks`) cannot be constrained to specific machine IDs today. The examples above apply to `instance_read` (and similar instance-scoped routes), not host SLA listing keys. + API keys using constraints must be created via the CLI ([`vastai create api-key`](/cli/reference/create-api-key)) or the API ([Create API Key](/api-reference/accounts/create-api-key)). diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 6f7b1f32..2dcb01bc 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -170,6 +170,7 @@ vastai search offers 'cpu_arch=arm64' | `pci_gen` | float | PCIE generation | | `pcie_bw` | float | PCIE bandwidth (CPU to GPU) | | `dph_total` | float | total $/hr in search results (compute + storage + SLA charge when applicable) | +| `search.slaPremiumPerHour` | float | SLA fee for this quote in `--raw` JSON (response field, not a query key) | | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability commitment on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 9227c32d..261e3d2c 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA. Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -Search can quote an SLA. The SLA starts only when you set **Reliability target** in the web console (and see an **SLA fee** line) or send `target_reliability` on REST `PUT /api/v0/asks/{id}/`. `vastai create instance` does not turn an SLA on. See [Create instance](/cli/reference/create-instance). +SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance). ## Instance Disk Size diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 8826ece9..2d434895 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -263,9 +263,22 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons #### Update SLA on an existing ask (partial body) -**Not a first listing.** The curl below adds SLA fields to a machine that already has base pricing. For a **first publish**, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include at least `min_chunk`, disk/bandwidth prices, and `end_date`) or **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). +**Not a first listing.** Use this SLA-only body when the machine already has base pricing. For a **first publish**, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include at least `min_chunk`, disk/bandwidth prices, and `end_date`) or **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). +```bash +curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"machine": 12345, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' +``` + +Do not copy example `price_gpu` or `end_date` from docs into a first listing—read current values from `vastai show machines --raw`. + +#### Full listing update (existing ask) + +When you also need to refresh GPU price or `end_date` on an already-listed machine: + ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ From 74f57b6309d5b58aa79477599b52b4ff39545e20 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:00:52 -0700 Subject: [PATCH 104/250] docs(sla): address doc-review consensus (cycle 60) Preserve fleet sla_sigma_x from raw JSON and prefer offers[].id for REST rent. Co-authored-by: Cursor --- host/sla-offers.mdx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 2d434895..585f0ad8 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -355,7 +355,8 @@ See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for ```bash export VAST_API_KEY="YOUR_API_KEY" -# Set DRY_RUN=0 to apply; default prints payloads only +# Leave DRY_RUN=1 until you confirm each machine is **Listed** (or on your allowlist). +# Set DRY_RUN=0 to apply. DRY_RUN="${DRY_RUN:-1}" machines=$(vastai show machines --raw) for id in $(vastai show machines -q); do @@ -371,9 +372,12 @@ for id in $(vastai show machines -q); do if ! echo "$machine" | jq -e '(.sla_r_claim // 0) > 0' >/dev/null; then echo "skip $id: no positive sla_r_claim (enable SLA per machine first)"; continue fi + if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then + echo "skip $id: sla_sigma_x missing in raw JSON (preserve confidence; do not default to 0.5)"; continue + fi body=$(echo "$machine" | jq -c \ '{machine: (.id|tonumber), price_gpu, end_date, min_chunk, - sla_r_claim, sla_sigma_x: (.sla_sigma_x // 0.5)}') + sla_r_claim, sla_sigma_x}') if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi From e2415fc1d38a2e581f107747ff72eb3500a636b5 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:00:58 -0700 Subject: [PATCH 105/250] docs(sla): address doc-review consensus (cycle 60) Prefer search offers[].id for REST rent instead of ask_contract_id or bundle_id. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c35912f6..c199bc70 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -233,7 +233,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -**2. Rent** the chosen offer. Use `offers[].id` (or `ask_contract_id`) from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Do not use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: +**2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: ```bash curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ From 89269481079ded510bdf36a0e75f155a9bbd0341 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:05:06 -0700 Subject: [PATCH 106/250] docs(sla): address doc-review consensus (cycle 61) State that rent bodies send only target_reliability, and iterate fleet re-list IDs from cached JSON. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 15 +++++++++++++-- host/sla-offers.mdx | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c199bc70..a26ea7b3 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -206,13 +206,15 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | | SLA service credits | **Account → Billing** | Not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | +**Rent body (SLA):** Send only `target_reliability` when creating a rental. Do not send `sla_r_claim`, `sla_r_target`, or other host listing fields on rent—they are ignored or invalid on create. + **Prerequisites (happy path):** Search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. Console users can skip this section. See the [Automation limits](#automation-limits) note in this section before you script search → rent → verify. For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). -Renters set **`target_reliability`** on search and on REST rent. **`sla_r_target`** is a stored field name in some instance filters — do not send it in the rent body. +Renters set **`target_reliability`** on search and on REST rent. Do not send **`sla_r_target`** or **`sla_r_claim`** in the rent body. **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -382,14 +384,23 @@ Console users: open **Instances** → select your instance → **price details**
API integrators: field names and filters +**Rent body (SLA):** Send only `target_reliability` when creating a rental. Host listing fields (`sla_r_claim`, `sla_r_target`) are read-only on the contract. + Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). To find instances with an SLA, filter **client-side** from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Prefer client-side filtering in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone to detect an SLA. -| Client-visible concept | Search / bundles | Active rental (`GET /api/v1/instances/`) | +**You set at search/rent** + +| Concept | Search / bundles | After rent (`GET /api/v1/instances/`) | | --- | --- | --- | | Your reliability target | `target_reliability` (quote only until rent) | `target_reliability` | | SLA charge rate | `search.slaPremiumPerHour` | `instance.slaPremiumPerHour` | + +**Host-locked on contract (read-only)** + +| Concept | Search / bundles | After rent (`GET /api/v1/instances/`) | +| --- | --- | --- | | Host reliability commitment | `expected_reliability` | `sla_r_claim` | Host ask field `sla_r_claim` on listings is host-side; on active rentals the locked reliability commitment appears as `sla_r_claim` in show-instances. Host confidence is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 585f0ad8..1ab4c734 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -359,7 +359,7 @@ export VAST_API_KEY="YOUR_API_KEY" # Set DRY_RUN=0 to apply. DRY_RUN="${DRY_RUN:-1}" machines=$(vastai show machines --raw) -for id in $(vastai show machines -q); do +for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') price=$(echo "$machine" | jq -r '.price_gpu // empty') From 85328c96e75385ad1563c533d936694fc20581e0 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:10:23 -0700 Subject: [PATCH 107/250] docs(sla): address doc-review consensus (cycle 62) Make missing SLA fee lines, earnings per_machine vs per_day, and search response fields harder to miss. Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 8 ++++++++ guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-offers.mdx | 2 ++ sdk/python/reference/create-instance.mdx | 2 +- 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 34bc3dde..f1fa7ad8 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create instance" Create a new instance -**SLA:** This command cannot set `target_reliability`. Search → rent with SLA is documented under [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers) (console or REST). Match `--disk` to any `--storage` you used in search. +**SLA:** This command cannot set `target_reliability`. If the instance price breakdown has no **SLA fee** / **SLA charge** line, you do **not** have an SLA—even if search showed SLA pricing. Enable SLA via console **RENT** (set **Reliability target**) or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). Match `--disk` to any `--storage` you used in search. ## Usage diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 2dcb01bc..d67fb227 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -184,6 +184,14 @@ vastai search offers 'cpu_arch=arm64' | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | +**SLA fields in `--raw` responses** (not query keys except as noted above): + +| Field | Meaning | +| --- | --- | +| `dph_total` | Total $/hr including SLA charge when you searched with `target_reliability` | +| `search.slaPremiumPerHour` | SLA fee for that quote | +| `expected_reliability` | Host reliability commitment on the offer | + SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console or REST create-instance flow documented in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 261e3d2c..0dfdcc7a 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA. Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance). +CLI and search filters only **quote** SLA pricing—they do not turn SLA on. Before **RENT**, set **Reliability target** again. If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index a26ea7b3..d9da40a7 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -36,7 +36,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua **Console quick start (no API key):** 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. -2. Set **Reliability target**, confirm an **SLA fee** line, then **RENT**. +2. Set **Reliability target**, confirm an **SLA fee** line, set instance disk on the slider, then **RENT**. Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. 3. Verify under **Instances**; after UTC settlement, check credits in **Account → Billing**. **If you used the CLI to search:** set **Reliability target** again in the web console before you click **RENT**. CLI filters do not carry over. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1ab4c734..81e4f5db 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -587,6 +587,8 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). +When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. Do not compare `per_day` totals to one machine’s backtester `worst_day_loss`. + ### Console (recommended for day-to-day checks) 1. Go to **Host → Billing** (or **Earnings** / **Reports**). diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 005c02c4..512c1b0a 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create_instance" Create a new instance from an offer/ask ID returned by search. -**SLA:** `target_reliability` is not available on `create_instance()` today. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). +**SLA:** `target_reliability` is not available on `create_instance()` today. If the instance price breakdown has no **SLA fee** / **SLA charge** line, you do **not** have an SLA—even if search showed SLA pricing. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). ## Signature From 764b0bd501dca2d5d74529e98bde53d3583c4726 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:10:32 -0700 Subject: [PATCH 108/250] docs(sla): address doc-review consensus (cycle 62) Keep SLA quote fields in a --raw response table, not mixed into search query keys. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index d67fb227..cd752ad4 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -169,8 +169,6 @@ vastai search offers 'cpu_arch=arm64' | `num_gpus` | int | number of GPUs | | `pci_gen` | float | PCIE generation | | `pcie_bw` | float | PCIE bandwidth (CPU to GPU) | -| `dph_total` | float | total $/hr in search results (compute + storage + SLA charge when applicable) | -| `search.slaPremiumPerHour` | float | SLA fee for this quote in `--raw` JSON (response field, not a query key) | | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability commitment on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | From 822f1c6e22f422341bd3728f8531a6c505d86cd6 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:15:31 -0700 Subject: [PATCH 109/250] docs(sla): address doc-review consensus (cycle 63) Explain fleet skip when sla_sigma_x is omitted and name REST rent as PUT /asks, not CLI create instance. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 4 ++-- cli/reference/show-earnings.mdx | 3 +++ guides/instances/choosing/sla-coverage.mdx | 6 +++--- host/sla-offers.mdx | 4 +++- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index e4e5804b..aa102c16 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -311,7 +311,7 @@ SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for - [Cancel Maintenance](/api-reference/machines/cancel-maint) - [Cleanup Machine](/api-reference/machines/cleanup-machine) -- [List Machine](/api-reference/machines/list-machine) +- [List Machine](/api-reference/machines/list-machine) — list/update offers: `PUT /api/v0/machines/create_asks` (`operationId: listMachine`) - [Remove Default Job](/api-reference/machines/remove-defjob) - [Schedule Maintenance](/api-reference/machines/schedule-maint) - [Set Default Job](/api-reference/machines/set-defjob) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index cd752ad4..10ebcff2 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -159,7 +159,7 @@ vastai search offers 'cpu_arch=arm64' | `gpu_frac` | float | ratio of GPUs in the offer to GPUs in the system | | `gpu_display_active` | bool | True if the GPU has a display attached | | `has_avx` | bool | CPU supports AVX instruction set | -| `id` | int | Offer/ask ID. Use this value when renting via create-instance (`PUT /api/v0/asks/{id}/`) | +| `id` | int | Offer/ask ID. Use this value as `{id}` on REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) | | `inet_down` | float | internet download speed in Mb/s | | `inet_down_cost` | float | internet download bandwidth cost in $/GB | | `inet_up` | float | internet upload speed in Mb/s | @@ -191,7 +191,7 @@ vastai search offers 'cpu_arch=arm64' | `expected_reliability` | Host reliability commitment on the offer | -SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console or REST create-instance flow documented in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. +SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console **RENT** flow or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": {"eq": 0.95}`. In that example `allocated_storage` is a number, not an operator object. If the CLI warns that an SLA search field is unrecognized, upgrade the CLI and check that the results still match the filters you set. diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index 762fc56f..c559e64d 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -29,10 +29,13 @@ vastai show earnings [OPTIONS] Machine id (optional) (alias: `--machine_id`) +`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (not fleet-wide `per_day[].sla_earn`). See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). + ## Examples ```bash vastai show earnings +vastai show earnings --raw | jq '.per_machine[] | {machid, sla_earn}' ``` ## Global Options diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d9da40a7..551916f7 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -30,7 +30,7 @@ A few things people mix up: Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). -**SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via the **REST API**, pass `target_reliability` on **create-instance** (`PUT /api/v0/asks/{id}/`). Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. +**SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via the **Create Instance API** (REST `PUT /api/v0/asks/{id}/` only—not `vastai create instance`), pass `target_reliability`. Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. **Console quick start (no API key):** @@ -122,10 +122,10 @@ Searching with a **reliability target of 95%** on an offer where the host's **re ## Finding SLA offers -**No SLA fee line in the price breakdown means you do not have an SLA.** Filtering to SLA listings or searching with a reliability target only quotes pricing. The SLA starts only when you set **Reliability target** in the console (or pass `target_reliability` on REST create-instance) before you rent. +**No SLA fee line in the price breakdown means you do not have an SLA.** Filtering to SLA listings or searching with a reliability target only quotes pricing. The SLA starts only when you set **Reliability target** in the console (or pass `target_reliability` on REST `PUT /api/v0/asks/{id}/`) before you rent. -**Decision rule:** Search filters **quote** SLA pricing only. The SLA starts only when you rent via the **web console** (Reliability target set) or **REST** create-instance (`target_reliability` on `PUT /api/v0/asks/{id}/`). The CLI cannot enable the SLA at rent time today — see [API automation](#api-automation) for the minimum REST rent path. +**Decision rule:** Search filters **quote** SLA pricing only. The SLA starts only when you rent via the **web console** (Reliability target set) or REST `PUT /api/v0/asks/{id}/` with `target_reliability` (not `vastai create instance`). The CLI cannot enable the SLA at rent time today — see [API automation](#api-automation) for the minimum REST rent path. ### In the web console diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 81e4f5db..b796a476 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -332,6 +332,8 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge This loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that already have `sla_r_claim > 0`. +`create_asks` defaults `sla_sigma_x` to `0.5` when you omit it on a write. This guide does **not** treat a missing `sla_sigma_x` in `show machines --raw` as that default—the raw payload may omit the field even when you intend Normal confidence. The loop **skips and logs** those IDs so it never silently writes `0.5`. Set **Confidence** in the console (or PUT `sla_sigma_x` for that machine), then re-run. A skip is not “SLA-ready.” + `PUT /api/v0/machines/create_asks/` **publishes a live listing** (same as **LIST**). A `sla_r_claim > 0` filter is **not** a listed-status check—running with `DRY_RUN=0` can put intentionally unlisted or paused machines back on the market. Before you apply, confirm each machine is **Listed** (or that you intend to re-list it) on **Host → Machines**. There is no documented `show machines --raw` field for listed vs unlisted in this guide; gate in the console or your own inventory before applying. @@ -373,7 +375,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: no positive sla_r_claim (enable SLA per machine first)"; continue fi if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then - echo "skip $id: sla_sigma_x missing in raw JSON (preserve confidence; do not default to 0.5)"; continue + echo "skip $id: sla_sigma_x missing in raw JSON (not SLA-ready; set Confidence / PUT sla_sigma_x, then re-run — do not assume 0.5)"; continue fi body=$(echo "$machine" | jq -c \ '{machine: (.id|tonumber), price_gpu, end_date, min_chunk, From 7394da56319b60b7bd1fd3844fb8f2280b3c961a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:18:58 -0700 Subject: [PATCH 110/250] docs(sla): address doc-review consensus (cycle 64) Correct offer id CLI usage and show-earnings jq machine_id so copy-paste monitoring works. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 +- cli/reference/show-earnings.mdx | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 10ebcff2..71876531 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -159,7 +159,7 @@ vastai search offers 'cpu_arch=arm64' | `gpu_frac` | float | ratio of GPUs in the offer to GPUs in the system | | `gpu_display_active` | bool | True if the GPU has a display attached | | `has_avx` | bool | CPU supports AVX instruction set | -| `id` | int | Offer/ask ID. Use this value as `{id}` on REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) | +| `id` | int | Offer/ask ID. Same `id` for `vastai create instance` (standard rent) or REST/console rent. For SLA, use REST `PUT /api/v0/asks/{id}/` or console **RENT** with **Reliability target**—CLI cannot set `target_reliability` | | `inet_down` | float | internet download speed in Mb/s | | `inet_down_cost` | float | internet download bandwidth cost in $/GB | | `inet_up` | float | internet upload speed in Mb/s | diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index c559e64d..f281b6f2 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -3,7 +3,11 @@ title: "vastai show earnings" sidebarTitle: "show earnings" --- -Get machine earning history reports +Get machine earning history reports. + + +Host settlement command. `sla_earn` is host SLA settlement, not renter credits. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [SLA credits](/guides/instances/choosing/sla-coverage#faq). + ## Usage @@ -29,13 +33,13 @@ vastai show earnings [OPTIONS] Machine id (optional) (alias: `--machine_id`) -`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (not fleet-wide `per_day[].sla_earn`). See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). +`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). ## Examples ```bash vastai show earnings -vastai show earnings --raw | jq '.per_machine[] | {machid, sla_earn}' +vastai show earnings --raw | jq '.per_machine[] | {machine_id, sla_earn}' ``` ## Global Options From ea866ec1d8681d0f305a96af43c756141938855e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:24:28 -0700 Subject: [PATCH 111/250] docs(sla): address doc-review consensus (cycle 65) Deduplicate renter SLA guardrails and put the renter key recipe after the renter heading. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 22 +++------------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index aa102c16..9d610d17 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -86,12 +86,12 @@ You can create scoped keys using: **For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. -**If you automate:** Search with `has_sla` → rent with `target_reliability` → confirm an SLA fee on the instance → view service credits in **Account → Billing**. - **Renter — search and REST rent.** +**Renter automation:** Search with `has_sla` → rent with `target_reliability` on `PUT /api/v0/asks/{id}/` → verify with `GET /api/v1/instances/`. Hosts: use the **Host — list, backtest, and earnings** recipe below. + Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. **Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. SLA credits appear only in the console. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 551916f7..e79399e4 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -29,10 +29,6 @@ A few things people mix up: Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). - -**SLA is opt-in.** In the console, set a reliability target in Search before you rent. Via the **Create Instance API** (REST `PUT /api/v0/asks/{id}/` only—not `vastai create instance`), pass `target_reliability`. Renting without a target means **no SLA charge and no SLA credits**, even on offers where the host has enabled SLA. - - **Console quick start (no API key):** 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. @@ -54,21 +50,11 @@ Full steps: [In the web console](#in-the-web-console). CLI/API limits for automa | Automate search → rent → verify | [API automation](#api-automation) | | View service credits | **Account → Billing** (console only today) | -**Console renters (web only).** You do not need an API key. Follow the steps in [In the web console](#in-the-web-console), then stop unless you automate. [API automation](#api-automation) is for API keys. - - -Match disk or storage size across search and rent. Defaults differ by channel (console 10 GB, REST search 8 GB, CLI search 5 GiB). Mixing channels can cause `invalid_price`. See the table under [API automation](#api-automation) before you automate. - +**Console renters (web only).** You do not need an API key. Follow [In the web console](#in-the-web-console), then stop unless you automate. -**CLI for search only** - -You cannot complete an SLA rental with `vastai create instance` alone. SLA is enabled at rent time in the web console or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. - -1. Search with SLA filters (`has_sla`, `target_reliability`) to see the quoted SLA fee. -2. Finish rent in the console: re-open Search, set **Reliability target** again (CLI filters do not carry over), confirm an **SLA fee** line, then **RENT**—or use REST with `target_reliability`. If **Instances → price details** has no SLA fee line, you do not have an SLA. -3. `vastai create instance` by itself does not turn on an SLA. +**CLI for search only:** quote with `search offers`, then enable SLA in the console or REST—not `vastai create instance`. Steps: [Finding SLA offers](#finding-sla-offers). SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/prepay contracts. See [Instance Pricing](/guides/instances/pricing). @@ -122,11 +108,9 @@ Searching with a **reliability target of 95%** on an offer where the host's **re ## Finding SLA offers -**No SLA fee line in the price breakdown means you do not have an SLA.** Filtering to SLA listings or searching with a reliability target only quotes pricing. The SLA starts only when you set **Reliability target** in the console (or pass `target_reliability` on REST `PUT /api/v0/asks/{id}/`) before you rent. +Search **quotes** SLA pricing. The SLA starts only when you set **Reliability target** at **RENT** (console) or pass `target_reliability` on REST `PUT /api/v0/asks/{id}/`. No SLA fee line in the price breakdown means you do not have an SLA. The CLI cannot enable SLA—see [API automation](#api-automation). -**Decision rule:** Search filters **quote** SLA pricing only. The SLA starts only when you rent via the **web console** (Reliability target set) or REST `PUT /api/v0/asks/{id}/` with `target_reliability` (not `vastai create instance`). The CLI cannot enable the SLA at rent time today — see [API automation](#api-automation) for the minimum REST rent path. - ### In the web console 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). From 5ab38424d75980b18840a81efff859dc63e1473f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:29:21 -0700 Subject: [PATCH 112/250] docs(sla): address doc-review consensus (cycle 66) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call out CLI→REST disk 5 vs 8, REST show-machines user_id, and fleet allowlist gating. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 ++ host/sla-offers.mdx | 17 ++++++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 9d610d17..b5416137 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -251,7 +251,7 @@ SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for - [Cloud Copy](/api-reference/instances/cloud-copy) - [Cancel Sync](/api-reference/instances/cancel-sync) - [Change Bid](/api-reference/instances/change-bid) -- [Create Instance](/api-reference/instances/create-instance) +- [Create Instance](/api-reference/instances/create-instance) — this endpoint does not accept `target_reliability`. SLA rent: `PUT /api/v0/asks/{id}/` ([renter recipe](#client-sla-scoped-key-recipe)). - [Manage Instance](/api-reference/instances/manage-instance) - [Delete Instance](/api-reference/instances/destroy-instance) - [Detach SSH Key](/api-reference/instances/detach-ssh-key) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index e79399e4..b25d6836 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -285,6 +285,8 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | REST search (`POST /api/v0/bundles/`) | 8 GB | `allocated_storage` | GB | | CLI (`vastai search offers`) | 5 GiB | `--storage` | GiB | +If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** before REST rent, or match the **same integer** on the console disk slider and REST `"disk"`. Example: `vastai search offers --storage 50` → console slider **50** → `"disk": 50` on `PUT /api/v0/asks/{id}/`. + **Match disk size when comparing prices.** Defaults differ by channel. When you rent with REST after a CLI search, pass the same number you searched with (for example `--storage 50` then `"disk": 50`). REST create-instance `disk` must be ≥ **8** when you pass it. The CLI search default of 5 is below that REST minimum. CLI help labels `--storage` as GiB and REST labels `disk` as GB. **Quoting rule:** Use the same disk number end-to-end for the channel you rent through (console slider, REST `disk` / `allocated_storage`, or CLI `--storage`). If you mix channels, set disk explicitly on every search and rent step. Treat the same integer as one quote across CLI GiB and REST GB labels unless the API returns a mismatch error (`invalid_price`). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index b796a476..64c507b0 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -319,6 +319,8 @@ Omitted non-SLA fields retain their current listing values; only fields present vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, sla_r_claim, sla_sigma_x, price_gpu, end_date}' ``` +REST equivalent: `GET /api/v0/machines?user_id={user_id}` (`user_id` is required). Get `user_id` from **Account → Profile** or `vastai show user`. The CLI supplies `user_id` for you. + Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge → PUT). `vastai list machine` and the Python SDK listing helpers cannot set SLA fields; start from this REST pattern (or the console) when you move an existing CLI listing to SLA. @@ -335,9 +337,14 @@ This loop does not turn an SLA on for new machines. Enable an SLA on each machin `create_asks` defaults `sla_sigma_x` to `0.5` when you omit it on a write. This guide does **not** treat a missing `sla_sigma_x` in `show machines --raw` as that default—the raw payload may omit the field even when you intend Normal confidence. The loop **skips and logs** those IDs so it never silently writes `0.5`. Set **Confidence** in the console (or PUT `sla_sigma_x` for that machine), then re-run. A skip is not “SLA-ready.” -`PUT /api/v0/machines/create_asks/` **publishes a live listing** (same as **LIST**). A `sla_r_claim > 0` filter is **not** a listed-status check—running with `DRY_RUN=0` can put intentionally unlisted or paused machines back on the market. Before you apply, confirm each machine is **Listed** (or that you intend to re-list it) on **Host → Machines**. There is no documented `show machines --raw` field for listed vs unlisted in this guide; gate in the console or your own inventory before applying. +`PUT /api/v0/machines/create_asks/` **publishes a live listing** (same as **LIST**). A `sla_r_claim > 0` filter is **not** a listed-status check—running with `DRY_RUN=0` can put intentionally unlisted or paused machines back on the market. Before you apply, confirm each machine is **Listed** on **Host → Machines**. There is no documented `show machines --raw` listed flag; keep an allowlist (CSV: `machine_id`, `intended_listed`) and only automate IDs with `intended_listed=true`. +**Fleet operators only.** Do not run the loop unless you manage a fleet. + + + + Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. **Before fleet SLA rollout:** @@ -359,9 +366,14 @@ See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for export VAST_API_KEY="YOUR_API_KEY" # Leave DRY_RUN=1 until you confirm each machine is **Listed** (or on your allowlist). # Set DRY_RUN=0 to apply. +# Only IDs in ALLOWLIST (intended_listed=true). Empty = skip all applies. +ALLOWLIST="${ALLOWLIST:-}" DRY_RUN="${DRY_RUN:-1}" machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do + if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then + echo "skip $id: not in ALLOWLIST"; continue + fi machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') price=$(echo "$machine" | jq -r '.price_gpu // empty') @@ -394,6 +406,9 @@ done Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. + + + **SLA-only update (existing ask only)** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep. Do **not** use this body for a first listing. ```bash From 19093e3db18a9d406c9dc4782afc17c9261e2a03 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:29:36 -0700 Subject: [PATCH 113/250] docs(sla): address doc-review consensus (cycle 66) Require ALLOWLIST before fleet DRY_RUN=0 so paused machines stay unlisted. Co-authored-by: Cursor --- host/sla-offers.mdx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 64c507b0..e3470d91 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -366,11 +366,14 @@ See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for export VAST_API_KEY="YOUR_API_KEY" # Leave DRY_RUN=1 until you confirm each machine is **Listed** (or on your allowlist). # Set DRY_RUN=0 to apply. -# Only IDs in ALLOWLIST (intended_listed=true). Empty = skip all applies. +# ALLOWLIST required for DRY_RUN=0 (space-separated listed machine IDs). ALLOWLIST="${ALLOWLIST:-}" DRY_RUN="${DRY_RUN:-1}" machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do + if [ "$DRY_RUN" = "0" ] && [ -z "$ALLOWLIST" ]; then + echo "abort: set ALLOWLIST to Listed machine IDs before DRY_RUN=0"; break + fi if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then echo "skip $id: not in ALLOWLIST"; continue fi From 6038c0ce789bb8c9bce840943abccaf21aaa80c5 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:33:04 -0700 Subject: [PATCH 114/250] docs(sla): address doc-review consensus (cycle 67) Align Create Instance vs target_reliability, rent body required fields, and dph_total in the CLI table. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 1 + guides/instances/choosing/sla-coverage.mdx | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b5416137..a61e3f36 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -251,7 +251,7 @@ SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for - [Cloud Copy](/api-reference/instances/cloud-copy) - [Cancel Sync](/api-reference/instances/cancel-sync) - [Change Bid](/api-reference/instances/change-bid) -- [Create Instance](/api-reference/instances/create-instance) — this endpoint does not accept `target_reliability`. SLA rent: `PUT /api/v0/asks/{id}/` ([renter recipe](#client-sla-scoped-key-recipe)). +- [Create Instance](/api-reference/instances/create-instance) — REST `PUT /api/v0/asks/{id}/` accepts `target_reliability`. CLI/SDK `create instance` / `create_instance()` cannot set it. See [renter recipe](#client-sla-scoped-key-recipe). - [Manage Instance](/api-reference/instances/manage-instance) - [Delete Instance](/api-reference/instances/destroy-instance) - [Detach SSH Key](/api-reference/instances/detach-ssh-key) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 71876531..a57f8d68 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -169,6 +169,7 @@ vastai search offers 'cpu_arch=arm64' | `num_gpus` | int | number of GPUs | | `pci_gen` | float | PCIE generation | | `pcie_bw` | float | PCIE bandwidth (CPU to GPU) | +| `dph_total` | float | total $/hr in `--raw` results (compute + storage + SLA charge when you searched with `target_reliability`; not a query key) | | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability commitment on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b25d6836..70108a1a 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -190,7 +190,7 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | | SLA service credits | **Account → Billing** | Not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | -**Rent body (SLA):** Send only `target_reliability` when creating a rental. Do not send `sla_r_claim`, `sla_r_target`, or other host listing fields on rent—they are ignored or invalid on create. +**Rent body (SLA):** Among SLA-related fields, send only `target_reliability` (not `sla_r_claim` / `sla_r_target`). Still include `image` or `template_hash_id` and a `disk` that matches your search quote. **Prerequisites (happy path):** Search with `has_sla` and your storage size, rent with `PUT` and the same `target_reliability`, then confirm the SLA on the instance. Console users can skip this section. @@ -370,7 +370,7 @@ Console users: open **Instances** → select your instance → **price details**
API integrators: field names and filters -**Rent body (SLA):** Send only `target_reliability` when creating a rental. Host listing fields (`sla_r_claim`, `sla_r_target`) are read-only on the contract. +**Rent body (SLA):** Among SLA-related fields, send only `target_reliability`. Host listing fields (`sla_r_claim`, `sla_r_target`) are read-only on the contract. Still send `image` or `template_hash_id` and matching `disk`. Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). From 06873243a039adce5a0371f1de2c635965761f67 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:37:02 -0700 Subject: [PATCH 115/250] docs(sla): address doc-review consensus (cycle 68) Clarify CLI create-instance vs SLA RENT and pin the UTC day-index example to a unix timestamp. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/create-instance.mdx | 9 +++++++-- cli/reference/search-offers.mdx | 2 +- host/sla-offers.mdx | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index a61e3f36..7e52c6f8 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -311,7 +311,7 @@ SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for - [Cancel Maintenance](/api-reference/machines/cancel-maint) - [Cleanup Machine](/api-reference/machines/cleanup-machine) -- [List Machine](/api-reference/machines/list-machine) — list/update offers: `PUT /api/v0/machines/create_asks` (`operationId: listMachine`) +- [List Machine](/api-reference/machines/list-machine) — list/update offers: `PUT /api/v0/machines/create_asks/` - [Remove Default Job](/api-reference/machines/remove-defjob) - [Schedule Maintenance](/api-reference/machines/schedule-maint) - [Set Default Job](/api-reference/machines/set-defjob) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index f1fa7ad8..20599570 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -6,7 +6,12 @@ sidebarTitle: "create instance" Create a new instance -**SLA:** This command cannot set `target_reliability`. If the instance price breakdown has no **SLA fee** / **SLA charge** line, you do **not** have an SLA—even if search showed SLA pricing. Enable SLA via console **RENT** (set **Reliability target**) or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). Match `--disk` to any `--storage` you used in search. +**SLA** + +- This command cannot set `target_reliability`. +- No **SLA fee** / **SLA charge** line in the price breakdown means you do **not** have an SLA (even if search quoted SLA). +- Enable SLA in the console (**RENT** → **Reliability target**) or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. +- See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). Match `--disk` to any `--storage` you used in search. ## Usage @@ -129,7 +134,7 @@ vastai create instance ID [OPTIONS] [--args ...] ## Description -Performs the same action as pressing the "RENT" button on the website at https://cloud.vast.ai/create/. +Performs the same action as pressing the "RENT" button on the website at https://cloud.vast.ai/create/ for standard on-demand rent. **SLA is different:** the CLI cannot set `target_reliability`. Creates an instance from an offer ID (which is returned from "search offers"). Each offer ID can only be used to create one instance. Besides the offer ID, you must pass either `--image` or `--template_hash`. A template supplies the image. `vastai create instance` cannot set `target_reliability`. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index a57f8d68..b946fd8c 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -70,7 +70,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] ## Description -**Query syntax** +**Query syntax (advanced)** The grammar below is for advanced filters. An SLA example is under [Examples](#examples). Search quotes an SLA; it does not turn one on (see the note at the top of this page). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e3470d91..a34b66e9 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -673,7 +673,7 @@ This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/ra When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` as UTC day indices (`day = floor(unix_epoch_seconds / 86400)`). Example: for `2026-07-24` UTC, `sday=eday=20658`. Prefer `last_days` when you do not need an absolute window. +- **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` as UTC day indices (`day = floor(unix_epoch_seconds / 86400)`). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Prefer `last_days` when you do not need an absolute window. - **Fleet snapshot:** one request without `machid` returns all machines in `per_machine[]` for the window: ```bash From 9afe2335ae8890f50fb0fb978c2050674dd974c9 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:41:53 -0700 Subject: [PATCH 116/250] docs(sla): address doc-review consensus (cycle 69) Keep dph_total as a --raw sort field, not a search query key, and rephrase interruptible SLA coverage. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 3 +-- host/sla-offers.mdx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index b946fd8c..ff534bd9 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -169,7 +169,6 @@ vastai search offers 'cpu_arch=arm64' | `num_gpus` | int | number of GPUs | | `pci_gen` | float | PCIE generation | | `pcie_bw` | float | PCIE bandwidth (CPU to GPU) | -| `dph_total` | float | total $/hr in `--raw` results (compute + storage + SLA charge when you searched with `target_reliability`; not a query key) | | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability commitment on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | @@ -183,7 +182,7 @@ vastai search offers 'cpu_arch=arm64' | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA fields in `--raw` responses** (not query keys except as noted above): +**SLA fields in `--raw` responses** (not query keys). Sort with `--order dph_total`. Do **not** put `dph_total` in the query string. | Field | Meaning | | --- | --- | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a34b66e9..f70812f9 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -65,7 +65,7 @@ On outage days you may still bill clients for **intended** compute **and** owe s -**Rental types:** The SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible instances on a machine with an SLA are not on the SLA; on-demand contracts on the same machine are. Reserved or prepay attempts on an offer with an SLA are not supported — use on-demand to rent with an SLA. +**Rental types:** The SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible rentals are not covered by the SLA, even on machines that offer SLA on on-demand. On-demand contracts on the same machine can have an SLA. Reserved or prepay attempts on an offer with an SLA are not supported — use on-demand to rent with an SLA. - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. From 310a1980bde91538165b0834616c384c357ff8ae Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:46:00 -0700 Subject: [PATCH 117/250] docs(sla): address doc-review consensus (cycle 70) Point renter credit reconciliation at the real CLI charges command, not a nonexistent show charges. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 70108a1a..59cc4b6f 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -341,7 +341,7 @@ Production settlement uses the multi-window reliability blend described above, n ### Settlement timing - Settlement runs **once per day** for the previous billing day (UTC). -- Service credits post to your **account balance**. View them under **Account → Billing** in the console. They do **not** appear as `items[].type` on `GET /api/v0/charges/`. Do not use the Charges API or `show charges` to reconcile SLA credits. +- Service credits post to your **account balance**. View them under **Account → Billing** in the console. They do **not** appear as `items[].type` on `GET /api/v0/charges/`. Do not use the Charges API or `vastai show invoices-v1 --charges` to reconcile SLA credits. - When your contract ends, any remaining unsettled days are resolved at close. ## If your instance goes down From b285945aefbb1269dfd4e5fa95157a2a28042ce5 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:51:11 -0700 Subject: [PATCH 118/250] docs(sla): address doc-review consensus (cycle 71) Echo per_machine sla_earn in the host key recipe and label the renter scoped-key recipe consistently. Co-authored-by: Cursor --- api-reference/permissions.mdx | 13 ++++++++----- guides/instances/choosing/sla-coverage.mdx | 6 ++++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 7e52c6f8..87549263 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -13,7 +13,7 @@ Console renters and hosts: you do not need this page to use SLA in the web conso | --- | --- | --- | | Rent with an SLA in the **web console** | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) — then leave this page | No | | List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) — then leave this page | No | -| Automate search, rent, or host listing | [Renter SLA recipe](#client-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | +| Automate search, rent, or host listing | [Renter SLA recipe](#renter-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | On this page, **renter** means client and **host** means provider. API names may still say client or provider. @@ -87,6 +87,7 @@ You can create scoped keys using: **For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. + **Renter — search and REST rent.** @@ -162,7 +163,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA**, then **LIST** | | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | -| Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings | +| Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings. Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | | Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key) | Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). @@ -228,13 +229,15 @@ You can also use **wildcards** in `params` to represent placeholder values, usef ## Endpoint Reference by Category +SLA automation: copy the JSON recipe above only. You do not need this encyclopedia unless you are building broader automation. + Copy the JSON from [SLA workflows](#sla-workflows-scoped-keys) before you scan the endpoint lists. Below is the complete mapping of which endpoints each permission category controls. ### instance\_read -SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#client-sla-scoped-key-recipe). +SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#renter-sla-scoped-key-recipe). - [Show Instance](/api-reference/instances/show-instance) — v0 path; not for SLA verification (use Show Instances v1 / `show instances-v1` as in the renter recipe). - [Show Instances](/api-reference/instances/show-instances) — this page is `GET /api/v1/instances/`. For SLA fields (`target_reliability`, `instance.slaPremiumPerHour`), use that API or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). Do not use `vastai show instances` for SLA checks. @@ -251,7 +254,7 @@ SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for - [Cloud Copy](/api-reference/instances/cloud-copy) - [Cancel Sync](/api-reference/instances/cancel-sync) - [Change Bid](/api-reference/instances/change-bid) -- [Create Instance](/api-reference/instances/create-instance) — REST `PUT /api/v0/asks/{id}/` accepts `target_reliability`. CLI/SDK `create instance` / `create_instance()` cannot set it. See [renter recipe](#client-sla-scoped-key-recipe). +- [Create Instance](/api-reference/instances/create-instance) — REST `PUT /api/v0/asks/{id}/` accepts `target_reliability`. CLI/SDK `create instance` / `create_instance()` cannot set it. See [renter recipe](#renter-sla-scoped-key-recipe). - [Manage Instance](/api-reference/instances/manage-instance) - [Delete Instance](/api-reference/instances/destroy-instance) - [Detach SSH Key](/api-reference/instances/detach-ssh-key) @@ -334,7 +337,7 @@ Host SLA keys: [Host SLA recipe](#host-sla-scoped-key-recipe). - [Search Offers](/api-reference/search/search-offers) - [Search Volumes](/api-reference/volumes/search-volumes) -Renter SLA keys: [Renter SLA recipe](#client-sla-scoped-key-recipe). +Renter SLA keys: [Renter SLA recipe](#renter-sla-scoped-key-recipe). ### team\_read diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 59cc4b6f..ae388135 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -180,7 +180,7 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ -**Before you use this section:** Create an API key under **Account → API Keys**, and be comfortable with REST and JSON. For a scoped key, see [Authentication](/api-reference/authentication) and the [renter SLA recipe](/api-reference/permissions#client-sla-scoped-key-recipe). If you prefer the UI, use [In the web console](#in-the-web-console) instead. +**Before you use this section:** Create an API key under **Account → API Keys**, and be comfortable with REST and JSON. For a scoped key, see [Authentication](/api-reference/authentication) and the [Renter SLA scoped-key recipe](/api-reference/permissions#renter-sla-scoped-key-recipe). If you prefer the UI, use [In the web console](#in-the-web-console) instead. | Capability | Console | REST | @@ -196,6 +196,8 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ See the [Automation limits](#automation-limits) note in this section before you script search → rent → verify. +Web app: [cloud.vast.ai](https://cloud.vast.ai). REST examples use `https://console.vast.ai/api/…`. + For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Renters set **`target_reliability`** on search and on REST rent. Do not send **`sla_r_target`** or **`sla_r_claim`** in the rent body. @@ -249,7 +251,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ `template_hash_id` is the content hash of a saved template. Include `template_hash_id` to rent from the template. Add `image` only when you want to override the template image. A request needs at least one of those fields. A template rent can send `template_hash_id` alone. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). -**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Client SLA scoped-key recipe](/api-reference/permissions#client-sla-scoped-key-recipe). +**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Renter SLA scoped-key recipe](/api-reference/permissions#renter-sla-scoped-key-recipe). **3. Verify.** Save `new_contract` from the rent response. Look that contract up with URL-encoded `select_filters` (`id` is a filterable column): From cc896ca0e8e771ce1cf7d676def0be9e297e4014 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 10:55:19 -0700 Subject: [PATCH 119/250] docs(sla): address doc-review consensus (cycle 72) Clarify that instance verify is not billing credits, and drop informal encyclopedia wording on permissions. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- host/hosting-overview.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 87549263..5eb2ba55 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -229,7 +229,7 @@ You can also use **wildcards** in `params` to represent placeholder values, usef ## Endpoint Reference by Category -SLA automation: copy the JSON recipe above only. You do not need this encyclopedia unless you are building broader automation. +SLA automation: copy the JSON recipe above only. You do not need the full endpoint lists below unless you are building broader automation. Copy the JSON from [SLA workflows](#sla-workflows-scoped-keys) before you scan the endpoint lists. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index ae388135..b3800125 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -267,7 +267,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). The server default `limit` can be as low as **5** (maximum **25**). - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. -**Billing reconciliation (console):** confirming the SLA does not show service credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. +**Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. **Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/` (`target_reliability`, `instance.slaPremiumPerHour`). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 693c09ee..5d034fc9 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -49,7 +49,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (uptime guarantee):** Optional add-on for on-demand listings. In short: you state a reliability **commitment**, the renter picks a **target**, they pay a small extra hourly fee, and if uptime misses that target they get a credit from your earnings. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language), then the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. Renters: [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). +- **SLA (uptime guarantee):** Optional add-on for on-demand listings. In short: you state a reliability **commitment**, the renter picks a **target**, they pay a small extra hourly fee, and if uptime misses that target they get a credit from your earnings. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language), then the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. Renters: [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). In renter-facing docs, **renter** means the same role as **client** (the person renting your machine). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. From 25598707e6b7fdd1f56ab41ec157966526cc1f39 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:04:39 -0700 Subject: [PATCH 120/250] docs(sla): address doc-review consensus (cycle 73) Point earnings poll limits at Show Earnings OpenAPI, keep console SLA off the permissions encyclopedia, and lead search-offers with examples. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 +-- cli/reference/create-instance.mdx | 2 ++ cli/reference/search-offers.mdx | 32 ++++++++++----------- guides/instances/choosing/find-and-rent.mdx | 2 +- host/sla-offers.mdx | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 5eb2ba55..39b349b6 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -7,6 +7,8 @@ sidebarTitle: "Permissions" ## You are here if… +**Console SLA users:** You do not need API keys for web-console SLA. Use the [renter SLA guide](/guides/instances/choosing/sla-coverage#in-the-web-console) or [host SLA guide](/host/sla-offers#web-console). The rest of this page is for scoped keys and automation. + Console renters and hosts: you do not need this page to use SLA in the web console. Renters: [In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console). Hosts: [Listing an SLA offer (console)](/host/sla-offers#web-console). | If you… | Start here | API key needed? | @@ -231,8 +233,6 @@ You can also use **wildcards** in `params` to represent placeholder values, usef SLA automation: copy the JSON recipe above only. You do not need the full endpoint lists below unless you are building broader automation. -Copy the JSON from [SLA workflows](#sla-workflows-scoped-keys) before you scan the endpoint lists. - Below is the complete mapping of which endpoints each permission category controls. ### instance\_read diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 20599570..4a2922a2 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -5,6 +5,8 @@ sidebarTitle: "create instance" Create a new instance + + **SLA** diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index ff534bd9..132d6b6e 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -70,21 +70,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] ## Description -**Query syntax (advanced)** - -The grammar below is for advanced filters. An SLA example is under [Examples](#examples). Search quotes an SLA; it does not turn one on (see the note at the top of this page). - -``` -query = comparison comparison... -comparison = field op value -field = -op = one of: <, <=, ==, !=, >=, >, in, notin -value = | 'any' | [value0, value1, ...] -bool = True | False -``` - -- Wrap `>` and `<` in quotes on the command line -- For string values (e.g. `gpu_name`), replace spaces with underscores: `RTX_3090` not `RTX 3090` +Filter examples (including SLA quotes) are under [Examples](#examples). Query syntax for advanced filters is at the end of Examples. ## Examples @@ -93,7 +79,7 @@ bool = True | False ```bash -# reliable single RTX 3090, no conflicts with stopped instances +# Marketplace reliability score (not SLA commitment) vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=False' # SLA search quote (enable the SLA at rent via console/REST — see SLA) @@ -125,6 +111,20 @@ vastai search offers 'reliability > 0.99 num_gpus>=4 verified=False rented=any' vastai search offers 'cpu_arch=arm64' ``` +**Query syntax (advanced)** + +``` +query = comparison comparison... +comparison = field op value +field = +op = one of: <, <=, ==, !=, >=, >, in, notin +value = | 'any' | [value0, value1, ...] +bool = True | False +``` + +- Wrap `>` and `<` in quotes on the command line +- For string values (e.g. `gpu_name`), replace spaces with underscores: `RTX_3090` not `RTX 3090` + ## Available Fields | Field | Type | Description | diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 0dfdcc7a..884ecc66 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA. Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -CLI and search filters only **quote** SLA pricing—they do not turn SLA on. Before **RENT**, set **Reliability target** again. If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance). +CLI and search filters only **quote** SLA pricing—they do not turn SLA on. Before **RENT**, set **Reliability target** again. If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). ## Instance Disk Size diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f70812f9..881980e8 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -665,7 +665,7 @@ Positive `sla_earn` = net SLA charge you kept that period; negative = net credit `GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key. See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Poll at most about once every two seconds per IP; back off on HTTP 429. +This endpoint is rate-limited. Poll `GET /api/v0/users/{user_id}/machine-earnings/` at most about once every two seconds for this route (OpenAPI `x-rate-limit` threshold `2.0` per request; see [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry. For daily SLA settlement, one pull with `last_days=1` after UTC rollover is usually enough. **Automation pattern:** There is no host webhook for SLA settlement. Poll `machine-earnings` with `last_days=1` and `machid`, alert on `per_machine[].sla_earn` thresholds, and call machines sequentially with backoff on 429. Do not use `per_day[].sla_earn` for a single machine. From 8725af64ada4c7ba210585a2bf5c660e1ca9528f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:08:43 -0700 Subject: [PATCH 121/250] docs(sla): address doc-review consensus (cycle 74) Collapse overlapping console-leave routing on the permissions page into one table. Co-authored-by: Cursor --- api-reference/permissions.mdx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 39b349b6..0755c99f 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -7,19 +7,17 @@ sidebarTitle: "Permissions" ## You are here if… -**Console SLA users:** You do not need API keys for web-console SLA. Use the [renter SLA guide](/guides/instances/choosing/sla-coverage#in-the-web-console) or [host SLA guide](/host/sla-offers#web-console). The rest of this page is for scoped keys and automation. +Use this page for scoped API keys and automation. If you only use the web console for SLA, follow the host or renter SLA guide instead—you do not need this page. -Console renters and hosts: you do not need this page to use SLA in the web console. Renters: [In the web console](/guides/instances/choosing/sla-coverage#in-the-web-console). Hosts: [Listing an SLA offer (console)](/host/sla-offers#web-console). - -| If you… | Start here | API key needed? | +| If you are… | Start here | API key needed? | | --- | --- | --- | -| Rent with an SLA in the **web console** | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) — then leave this page | No | -| List SLA offers in the **Host** console | [SLA Offers](/host/sla-offers#web-console) — then leave this page | No | -| Automate search, rent, or host listing | [Renter SLA recipe](#renter-sla-scoped-key-recipe) or [Host SLA recipe](#host-sla-scoped-key-recipe) on this page | Yes | +| Renter (console) | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) | No | +| Host (console) | [SLA Offers](/host/sla-offers#web-console) | No | +| Automating search, rent, or listing | Continue below ([renter recipe](#renter-sla-scoped-key-recipe) · [host recipe](#host-sla-scoped-key-recipe)) | Yes | On this page, **renter** means client and **host** means provider. API names may still say client or provider. -Every API key has a set of permissions that control which endpoints it can access. This page is the reference for permission categories, how they map to API routes, and how to build scoped keys. Everything under **Automation only** is for scripted search, listing, and earnings. +The sections below define permission categories and JSON recipes for renter and host SLA workflows. For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). From ede32a0b7841f5df945553bda05a7b5de7f645c9 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:15:08 -0700 Subject: [PATCH 122/250] docs(sla): address doc-review consensus (cycle 75) Align Reliability target with Search filters, harden fleet backtest success checks, and expand show-earnings SLA examples. Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 8 +++--- cli/reference/show-earnings.mdx | 9 ++++-- guides/instances/choosing/sla-coverage.mdx | 6 ++-- host/sla-backtester.mdx | 33 ++++++++++++++-------- snippets/host/cli/list-machine.mdx | 2 +- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 4a2922a2..58e0da1a 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -12,7 +12,7 @@ Create a new instance - This command cannot set `target_reliability`. - No **SLA fee** / **SLA charge** line in the price breakdown means you do **not** have an SLA (even if search quoted SLA). -- Enable SLA in the console (**RENT** → **Reliability target**) or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. +- Enable SLA in the console: **Search filters** (left bar) → **Reliability target**, confirm **SLA fee**, then **RENT**—or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. - See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). Match `--disk` to any `--storage` you used in search. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 132d6b6e..afb824f0 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -12,7 +12,7 @@ Search can quote an SLA. The CLI cannot enable SLA at rent—use the [web consol **If you only use the CLI today** 1. Use `search offers` to compare quotes (SLA filters are optional). -2. To rent with SLA, open the console **RENT** flow with **Reliability target** set, or follow [API automation](/guides/instances/choosing/sla-coverage#api-automation). `vastai create instance` cannot set `target_reliability`. +2. To rent with SLA, open console Search, set **Reliability target** in the **left Search filters**, confirm an **SLA fee** line, then **RENT**—or follow [API automation](/guides/instances/choosing/sla-coverage#api-automation). `vastai create instance` cannot set `target_reliability`. ## Usage @@ -89,7 +89,7 @@ vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability -**Next step for SLA:** Search only quotes SLA pricing. Enable SLA at rent in the web console (**Reliability target** on **RENT**) or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. Do not use `vastai create instance` expecting SLA. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**Next step for SLA:** Search only quotes SLA pricing. Enable SLA in the web console (**Reliability target** in **Search filters**, then **RENT**) or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. Do not use `vastai create instance` expecting SLA. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash # datacenter GPUs with minimum compute capability and TFLOPs @@ -159,7 +159,7 @@ bool = True | False | `gpu_frac` | float | ratio of GPUs in the offer to GPUs in the system | | `gpu_display_active` | bool | True if the GPU has a display attached | | `has_avx` | bool | CPU supports AVX instruction set | -| `id` | int | Offer/ask ID. Same `id` for `vastai create instance` (standard rent) or REST/console rent. For SLA, use REST `PUT /api/v0/asks/{id}/` or console **RENT** with **Reliability target**—CLI cannot set `target_reliability` | +| `id` | int | Offer/ask ID. Same `id` for `vastai create instance` (standard rent) or REST/console rent. For SLA, use REST `PUT /api/v0/asks/{id}/` or console Search filters **Reliability target** then **RENT**—CLI cannot set `target_reliability` | | `inet_down` | float | internet download speed in Mb/s | | `inet_down_cost` | float | internet download bandwidth cost in $/GB | | `inet_up` | float | internet upload speed in Mb/s | @@ -191,7 +191,7 @@ bool = True | False | `expected_reliability` | Host reliability commitment on the offer | -SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use the console **RENT** flow or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. +SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": {"eq": 0.95}`. In that example `allocated_storage` is a number, not an operator object. If the CLI warns that an SLA search field is unrecognized, upgrade the CLI and check that the results still match the filters you set. diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index f281b6f2..247872e8 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -6,7 +6,7 @@ sidebarTitle: "show earnings" Get machine earning history reports. -Host settlement command. `sla_earn` is host SLA settlement, not renter credits. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [SLA credits](/guides/instances/choosing/sla-coverage#faq). +Host settlement command. `sla_earn` is host SLA settlement, not renter credits. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [Where do I see historical SLA credits?](/guides/instances/choosing/sla-coverage#where-do-i-see-historical-sla-credits). ## Usage @@ -26,20 +26,23 @@ vastai show earnings [OPTIONS] - end date and time for report. Many formats accepted (alias: `--end_date`) + end date and time for report. Many formats accepted (alias: `--end_date`) Machine id (optional) (alias: `--machine_id`) -`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). +`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). For one machine / one UTC day, see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). ## Examples ```bash vastai show earnings vastai show earnings --raw | jq '.per_machine[] | {machine_id, sla_earn}' +# One machine (prefer --machine_id for SLA settlement checks) +vastai show earnings --machine_id 12345 --start_date $(date -u -d 'yesterday' +%F) --end_date $(date -u -d 'yesterday' +%F) --raw \ + | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` ## Global Options diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b3800125..b1398a06 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -32,10 +32,10 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua **Console quick start (no API key):** 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. -2. Set **Reliability target**, confirm an **SLA fee** line, set instance disk on the slider, then **RENT**. Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. +2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. 3. Verify under **Instances**; after UTC settlement, check credits in **Account → Billing**. -**If you used the CLI to search:** set **Reliability target** again in the web console before you click **RENT**. CLI filters do not carry over. +**If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. Full steps: [In the web console](#in-the-web-console). CLI/API limits for automation are under [API automation](#api-automation). @@ -108,7 +108,7 @@ Searching with a **reliability target of 95%** on an offer where the host's **re ## Finding SLA offers -Search **quotes** SLA pricing. The SLA starts only when you set **Reliability target** at **RENT** (console) or pass `target_reliability` on REST `PUT /api/v0/asks/{id}/`. No SLA fee line in the price breakdown means you do not have an SLA. The CLI cannot enable SLA—see [API automation](#api-automation). +Search **quotes** SLA pricing. The SLA starts only when you set **Reliability target** in the console **Search filters** (left bar) before **RENT**, or pass `target_reliability` on REST `PUT /api/v0/asks/{id}/`. No SLA fee line in the price breakdown means you do not have an SLA. The CLI cannot enable SLA—see [API automation](#api-automation). ### In the web console diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index b2715671..1c812c17 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -301,24 +301,35 @@ export VAST_API_KEY="YOUR_API_KEY" 2. Run backtests **sequentially** (one machine at a time). Set `r` to each machine’s **candidate** reliability commitment (the `sla_r_claim` you plan to list)—do not assume a fleet-wide `0.95` if you intend to list at `0.99` or another value: ```bash -# Example uses R=0.99; change per machine or read from your inventory CSV. -R="${R:-0.99}" -for id in $(vastai show machines -q); do - resp=$(curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$R&p=0.6667" \ - || echo '{"error":"request_failed"}') - if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then - echo "machine_id=$id error: $(echo "$resp" | jq -r '.error')" - else - echo "$resp" | jq '{machine_id: '"$id"', r: '"$R"', worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' +# Prefer each machine's planned sla_r_claim from show machines --raw. +# Uniform fleet override: export R=0.99 before the loop. +machines=$(vastai show machines --raw) +for id in $(echo "$machines" | jq -r '.machines[].id'); do + r="${R:-}" + if [ -z "$r" ]; then + r=$(echo "$machines" | jq -r --arg id "$id" \ + '.machines[] | select((.id|tostring) == $id) | .sla_r_claim // empty') fi + if ! echo "$r" | jq -e '. > 0' >/dev/null 2>&1; then + echo "skip $id: set candidate sla_r_claim (or export R=0.99 for a uniform fleet)"; continue + fi + http=$(curl -s -o /tmp/sla_bt_$id.json -w "%{http_code}" \ + -H "Authorization: Bearer $VAST_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$r&p=0.6667") + if [ "$http" != "200" ] || ! jq -e '.success == true' /tmp/sla_bt_$id.json >/dev/null 2>&1; then + echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' /tmp/sla_bt_$id.json 2>/dev/null)" + sleep 2; continue + fi + jq -c --arg id "$id" --argjson r "$r" \ + '{machine_id: $id, r: $r, worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' \ + /tmp/sla_bt_$id.json sleep 2 done ``` Expect roughly two seconds per machine minimum (`sleep 2` plus request time). For 50 machines, budget at least a few minutes. Run off-peak before a fleet SLA rollout. On `429`, back off per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Parallel requests are not recommended unless you implement backoff. -3. Compare `worst_day_loss` and `total_sla` across machines at the same `r` you will list. +3. Compare `worst_day_loss` and `total_sla` across machines at the **`r` each will list** (or at one shared `R` if the fleet is uniform). 4. Apply matching `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). ## When stuck diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 863b1404..489e463a 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -49,7 +49,7 @@ vastai list machine ID [options] - contract offer expiration - the available until date (optional, in unix float timestamp or MM/DD/YYYY format) (alias: `--end_date`) + Offer expiration date (optional): Unix timestamp or `MM/DD/YYYY` (alias: `--end_date`) From eb87f98ee889fb3e24ba89b60aa399fc25f6d801 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:18:19 -0700 Subject: [PATCH 123/250] docs(sla): address doc-review consensus (cycle 76) Clarify earnings poll wording, SLA-before-LIST checklist order, and Normal-confidence fleet backtest p. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 ++ host/sla-backtester.mdx | 2 ++ host/sla-offers.mdx | 4 ++-- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index afb824f0..238f6b52 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -188,7 +188,7 @@ bool = True | False | --- | --- | | `dph_total` | Total $/hr including SLA charge when you searched with `target_reliability` | | `search.slaPremiumPerHour` | SLA fee for that quote | -| `expected_reliability` | Host reliability commitment on the offer | +| `expected_reliability` | Host reliability commitment (also a query key; see Available Fields) | SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b1398a06..88f72ae9 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -31,6 +31,8 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua **Console quick start (no API key):** +Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) has credit or a payment method, and pick a [template](/guides/instances/choosing/templates) in Search (see [Finding & Renting](/guides/instances/choosing/find-and-rent)). + 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. 2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. 3. Verify under **Instances**; after UTC settlement, check credits in **Account → Billing**. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 1c812c17..aa9efe9c 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -303,6 +303,8 @@ export VAST_API_KEY="YOUR_API_KEY" ```bash # Prefer each machine's planned sla_r_claim from show machines --raw. # Uniform fleet override: export R=0.99 before the loop. +# This sample uses Normal confidence only (p=0.6667). For Tight/Wide listings, +# map each machine's sla_sigma_x → p via the confidence table before calling the API. machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do r="${R:-}" diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 881980e8..ab36562b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -34,7 +34,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist -1. Complete [host setup](https://cloud.vast.ai/host/setup/) and list your machine. +1. Complete [host setup](https://cloud.vast.ai/host/setup/) and confirm the machine appears on **Host → Machines** (healthy, priced). If you want SLA from the first rental, finish **Set Pricing → SLA** before your first **LIST** (see [Web console](#web-console)). 2. Test on a [separate client account](/host/hosting-overview#testing-your-own-machine) (billed like any rental). 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). @@ -665,7 +665,7 @@ Positive `sla_earn` = net SLA charge you kept that period; negative = net credit `GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key. See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited. Poll `GET /api/v0/users/{user_id}/machine-earnings/` at most about once every two seconds for this route (OpenAPI `x-rate-limit` threshold `2.0` per request; see [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry. For daily SLA settlement, one pull with `last_days=1` after UTC rollover is usually enough. +This endpoint is rate-limited. Poll `GET /api/v0/users/{user_id}/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, one pull with `last_days=1` after UTC rollover is usually enough. **Automation pattern:** There is no host webhook for SLA settlement. Poll `machine-earnings` with `last_days=1` and `machid`, alert on `per_machine[].sla_earn` thresholds, and call machines sequentially with backoff on 429. Do not use `per_day[].sla_earn` for a single machine. From 805605fb91b6c676dc534f66c8a23dfc9fa9c851 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:22:18 -0700 Subject: [PATCH 124/250] docs(sla): address doc-review consensus (cycle 77) Add show-earnings rate-limit guidance, map fleet backtest p from sla_sigma_x, and align bundles search defaults with CLI. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 +- cli/reference/show-earnings.mdx | 6 ++++- guides/instances/choosing/sla-coverage.mdx | 6 +++++ host/sla-backtester.mdx | 26 ++++++++++++++-------- host/sla-offers.mdx | 2 +- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 238f6b52..b6c1f636 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -182,7 +182,7 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA fields in `--raw` responses** (not query keys). Sort with `--order dph_total`. Do **not** put `dph_total` in the query string. +**SLA fields in `--raw` responses** (not query keys, except `expected_reliability` which is both a filter and a response field). Sort with `--order dph_total`. Do **not** put `dph_total` in the query string. | Field | Meaning | | --- | --- | diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index 247872e8..1522bf02 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -3,12 +3,16 @@ title: "vastai show earnings" sidebarTitle: "show earnings" --- -Get machine earning history reports. +Get machine earnings history reports. Host settlement command. `sla_earn` is host SLA settlement, not renter credits. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [Where do I see historical SLA credits?](/guides/instances/choosing/sla-coverage#where-do-i-see-historical-sla-credits). + +Host SLA settlement monitoring is rate-limited (safe default: about once every two seconds; back off on **429**). Use a key with `billing_read`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing) and [Show Earnings](/api-reference/billing/show-earnings). + + ## Usage ```bash diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 88f72ae9..a339912e 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -215,6 +215,8 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ "type": "ondemand", "verified": {"eq": true}, "rentable": {"eq": true}, + "external": {"eq": false}, + "rented": {"eq": false}, "allocated_storage": 50, "order": [["dph_total", "asc"]], "target_reliability": {"eq": 0.95}, @@ -223,6 +225,8 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` +CLI search defaults include `external=false` and `rented=false`; include those keys on REST so quotes match CLI. + **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: ```bash @@ -236,6 +240,8 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ }' ``` +On-demand REST rent with default `cancel_unavail` may return **HTTP 410** if the offer cannot start immediately. Re-search and pick a new ask—do not backoff-retry the same id (see the error table below). + See [Create Instance](/api-reference/instances/create-instance) and [Search Offers](/api-reference/search/search-offers). **Rent with a template** (the template supplies the image; still send the same target and enough disk): diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index aa9efe9c..85982753 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -301,29 +301,37 @@ export VAST_API_KEY="YOUR_API_KEY" 2. Run backtests **sequentially** (one machine at a time). Set `r` to each machine’s **candidate** reliability commitment (the `sla_r_claim` you plan to list)—do not assume a fleet-wide `0.95` if you intend to list at `0.99` or another value: ```bash -# Prefer each machine's planned sla_r_claim from show machines --raw. -# Uniform fleet override: export R=0.99 before the loop. -# This sample uses Normal confidence only (p=0.6667). For Tight/Wide listings, -# map each machine's sla_sigma_x → p via the confidence table before calling the API. +# Prefer each machine's planned sla_r_claim / sla_sigma_x from show machines --raw. +# Uniform r override: export R=0.99. Map sla_sigma_x → p via Confidence values table. machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do r="${R:-}" + machine=$(echo "$machines" | jq -c --arg id "$id" \ + '.machines[] | select((.id|tostring) == $id)') if [ -z "$r" ]; then - r=$(echo "$machines" | jq -r --arg id "$id" \ - '.machines[] | select((.id|tostring) == $id) | .sla_r_claim // empty') + r=$(echo "$machine" | jq -r '.sla_r_claim // empty') fi if ! echo "$r" | jq -e '. > 0' >/dev/null 2>&1; then echo "skip $id: set candidate sla_r_claim (or export R=0.99 for a uniform fleet)"; continue fi + if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then + echo "skip $id: sla_sigma_x missing (set Confidence / PUT sla_sigma_x before backtest)"; continue + fi + # Approx bands from Confidence values (p): Tight≈0.2 → 0.83, Normal≈0.5 → 0.6667, Wide≈1.0 → 0.50 + p=$(echo "$machine" | jq -r ' + .sla_sigma_x as $s + | if $s <= 0.35 then 0.83 + elif $s <= 0.75 then 0.6667 + else 0.50 end') http=$(curl -s -o /tmp/sla_bt_$id.json -w "%{http_code}" \ -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$r&p=0.6667") + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$r&p=$p") if [ "$http" != "200" ] || ! jq -e '.success == true' /tmp/sla_bt_$id.json >/dev/null 2>&1; then echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' /tmp/sla_bt_$id.json 2>/dev/null)" sleep 2; continue fi - jq -c --arg id "$id" --argjson r "$r" \ - '{machine_id: $id, r: $r, worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' \ + jq -c --arg id "$id" --argjson r "$r" --argjson p "$p" \ + '{machine_id: $id, r: $r, p: $p, worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' \ /tmp/sla_bt_$id.json sleep 2 done diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index ab36562b..c260a434 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -673,7 +673,7 @@ This endpoint is rate-limited. Poll `GET /api/v0/users/{user_id}/machine-earning When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** use `last_days=1` with `machid` set, or `sday`/`eday` as UTC day indices (`day = floor(unix_epoch_seconds / 86400)`). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Prefer `last_days` when you do not need an absolute window. +- **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs backtester `worst_day_loss`), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` for that calendar day. Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. - **Fleet snapshot:** one request without `machid` returns all machines in `per_machine[]` for the window: ```bash From 8afd28bc2f089eb1716dd08ffb6569ede7acf589 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:25:17 -0700 Subject: [PATCH 125/250] docs(sla): address doc-review consensus (cycle 78) Add a copy-paste sday/eday earnings example and a host jump link ahead of the renter key recipe. Co-authored-by: Cursor --- host/sla-offers.mdx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index c260a434..f439075c 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -674,7 +674,15 @@ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA sett **Quick rules:** - **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs backtester `worst_day_loss`), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` for that calendar day. Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. -- **Fleet snapshot:** one request without `machid` returns all machines in `per_machine[]` for the window: + +```bash +# Exact UTC day 2026-07-24 for machine 12345 (sday/eday = 20658) +curl -s -H "Authorization: Bearer $VAST_API_KEY" \ + "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?machid=12345&sday=20658&eday=20658" \ + | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' +``` + +- **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window: ```bash curl -s -H "Authorization: Bearer $VAST_API_KEY" \ @@ -683,7 +691,7 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ ``` -**Machine-scoped one-day total:** +**Machine-scoped coarse poll (`last_days=1`, not a settled calendar day):** ```bash curl -s -H "Authorization: Bearer $VAST_API_KEY" \ From 22b7fd1398b664e8fe8ac4f467444d56d9e36ccb Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:25:23 -0700 Subject: [PATCH 126/250] docs(sla): address doc-review consensus (cycle 78) Add a host jump link ahead of the renter scoped-key recipe on permissions. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 0755c99f..9eb8cead 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -86,6 +86,8 @@ You can create scoped keys using: **For API automation:** Copy only the JSON in the renter or host recipe below. You do not need the endpoint lists later on this page. +**Hosts:** Jump to [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe). + From 1584931626de43fdc1d254f61b46d511c2a6f7e9 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:28:56 -0700 Subject: [PATCH 127/250] docs(sla): address doc-review consensus (cycle 79) Harden fleet backtest r validation, link CLI --storage to channel defaults, and clarify Save vs LIST and Destroy paths. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 5 +++-- host/sla-backtester.mdx | 9 +++++---- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 9eb8cead..2870498d 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -162,7 +162,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | Task | Permission | Console fallback | | --- | --- | --- | -| List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA**, then **LIST** | +| List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA** → **Save**. First publish: **Save** → **LIST**. Already listed: **Save** only ([Web console](/host/sla-offers#web-console)) | | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings. Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index b6c1f636..472d1ae8 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -61,7 +61,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] - Amount of storage to use for pricing, in GiB. default=5.0GiB + Amount of storage to use for pricing, in GiB. default=5.0GiB. Console, REST, and CLI use different default disk sizes—see [SLA coverage → API automation](/guides/instances/choosing/sla-coverage#api-automation) before REST rent after a CLI search. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index a339912e..c5e4baa4 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -358,8 +358,9 @@ Production settlement uses the multi-window reliability blend described above, n 1. Save work and check **Instances** for host/maintenance status. 2. Remember: compute and SLA charges continue until settlement; credits apply to the **previous UTC day**, not the current hour. -3. After settlement, check **Account → Billing** in the console for SLA line items (not `GET /api/v0/charges/`). -4. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). +3. **Console:** Open **Instances**, select the instance, then **Destroy** to stop future charges. Stopping alone may not end billing for a broken instance—see [Stop vs destroy](#what-you-pay-during-an-outage). +4. After settlement, check **Account → Billing** in the console for SLA line items (not `GET /api/v0/charges/`). +5. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). ## Viewing SLA on active instances diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 85982753..9bad45b8 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -311,13 +311,14 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -z "$r" ]; then r=$(echo "$machine" | jq -r '.sla_r_claim // empty') fi - if ! echo "$r" | jq -e '. > 0' >/dev/null 2>&1; then - echo "skip $id: set candidate sla_r_claim (or export R=0.99 for a uniform fleet)"; continue + if ! jq -n --arg r "$r" '($r | tonumber?) > 0' >/dev/null 2>&1; then + echo "skip $id: set Claim in console (**Set Pricing → SLA**) or export R=0.99"; continue fi if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then - echo "skip $id: sla_sigma_x missing (set Confidence / PUT sla_sigma_x before backtest)"; continue + echo "skip $id: set Confidence in console or PUT sla_sigma_x before backtest"; continue fi - # Approx bands from Confidence values (p): Tight≈0.2 → 0.83, Normal≈0.5 → 0.6667, Wide≈1.0 → 0.50 + # Approx bands from Confidence values (p): Tight≈0.2 → 0.83, Normal≈0.5 → 0.6667, Wide≈1.0 → 0.50. + # Non-table sla_sigma_x values map to the nearest band; for custom spreads, pass p explicitly. p=$(echo "$machine" | jq -r ' .sla_sigma_x as $s | if $s <= 0.35 then 0.83 From 778643a400d2315257bb5440a17846b9e53fc0d1 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:32:30 -0700 Subject: [PATCH 128/250] docs(sla): address doc-review consensus (cycle 80) Harden 429 rent recovery, use relative maintenance start times, and note CLI vs REST gpu_ram units. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-offers.mdx | 8 ++++---- snippets/host/cli/schedule-maint.mdx | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 472d1ae8..0e25e4d1 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -154,7 +154,7 @@ bool = True | False | `gpu_max_temp` | float | GPU temp limit (°C) | | `gpu_mem_bw` | float | GPU memory bandwidth in GB/s | | `gpu_name` | string | GPU model name (no quotes, replace spaces with underscores, ie: RTX_3090) | -| `gpu_ram` | float | per GPU RAM in GB | +| `gpu_ram` | float | per GPU RAM in GB (CLI query). REST `POST /api/v0/bundles/` `gpu_ram` filters use MB—follow [Search Offers OpenAPI](/api-reference/search/search-offers) for REST. | | `gpu_total_ram` | float | total GPU RAM in GB | | `gpu_frac` | float | ratio of GPUs in the offer to GPUs in the system | | `gpu_display_active` | bool | True if the GPU has a display attached | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c5e4baa4..b95b38c7 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -286,7 +286,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Offer not found or not available | HTTP 404 `invalid_args` (`msg` may include `no_such_ask`) | Do not retry that id; search again and rent a current offer | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | -| Too many requests | HTTP 429 | Wait and retry the same rent. The API may return `API requests too frequent` | +| Too many requests | HTTP 429 | Wait and back off. Before retrying the same `PUT`, confirm with `GET /api/v1/instances/` whether the contract already exists. If retry returns `invalid_price`, `no_such_ask`, 404, or 410, re-search with the same `target_reliability` and storage, then rent a fresh offer id. | | SLA with a bid or interruptible offer | Rent does not turn on an SLA | Search with `"type": "ondemand"`. Do not send `price` or `bid_price` when you want an SLA. | | Channel | Default storage | Field | Units (label) | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f439075c..fa80dbd7 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -571,15 +571,15 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** Schedule maintenance **sequentially** across a fleet. On HTTP 429, wait and retry with backoff (for example, `sleep 2` between machines). See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash -# Planned window: 2026-08-01 02:00:00 UTC (≥24 hours ahead when you run this) -# Prefer computing the epoch so the comment and value stay in sync: +# Planned window ≥24 hours ahead (Linux GNU date). Example: day after tomorrow 02:00 UTC. +# macOS: date -u -j -v+2d -v2H -v0M -v0S +%s vastai schedule maint MACHINE_ID \ - --sdate "$(date -u -d '2026-08-01 02:00:00' +%s)" \ + --sdate "$(date -u -d '2 days 02:00:00' +%s)" \ --duration 2 \ --maintenance_category software ``` -REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate": "2026-08-01T02:00:00Z"` (optional `"maintenance_reason": "OS kernel upgrade"`) — see [Schedule Maintenance](/api-reference/machines/schedule-maint). +REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate"` as ISO 8601 UTC at least 24 hours ahead (optional `"maintenance_reason": "OS kernel upgrade"`) — see [Schedule Maintenance](/api-reference/machines/schedule-maint). **Cancel or reschedule:** To cancel a window, use [`vastai cancel maint`](/host/cli/cancel-maint) (requires `machine_write`) or the [REST cancel-maintenance API](/api-reference/machines/cancel-maint). To reschedule, cancel the existing window, then run `schedule maint` with a new `--sdate` (still ≥24 hours ahead for planned SLA maintenance). diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 7677446c..b31a2265 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -46,10 +46,10 @@ If SLA is enabled and you need planned downtime during an active rental, schedul ```bash # Replace MACHINE_ID; --sdate must be a future UTC epoch (≥24h ahead for planned credit review) -# Linux: date -u -d '2026-08-01 02:00:00' +%s -# macOS: date -u -j -f '%Y-%m-%d %H:%M:%S' '2026-08-01 02:00:00' +%s +# Linux: date -u -d '2 days 02:00:00' +%s +# macOS: date -u -j -v+2d -v2H -v0M -v0S +%s vastai schedule maint MACHINE_ID \ - --sdate "$(date -u -d '2026-08-01 02:00:00' +%s)" \ + --sdate "$(date -u -d '2 days 02:00:00' +%s)" \ --duration 2 \ --maintenance_category software ``` From 816906afa8270a01301890dec7201268bcaf8d4e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:36:51 -0700 Subject: [PATCH 129/250] docs(sla): address doc-review consensus (cycle 81) Guard fleet end_date, align CLI search defaults, clarify Search filters vs CLI, and harden backtester fleet hygiene. Co-authored-by: Cursor --- guides/instances/choosing/find-and-rent.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 12 ++++++----- host/sla-backtester.mdx | 23 +++++++++++++-------- host/sla-offers.mdx | 19 ++++++++++++----- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 884ecc66..222ea045 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -58,10 +58,10 @@ All stats shown are the portion of the total machine rented. - Max Duration: The maximum length of a rental contract on this machine - Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host reliability commitment. - Rental Option: RENT button -- **SLA (optional):** On-demand offers may include an optional SLA. Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). +- **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -CLI and search filters only **quote** SLA pricing—they do not turn SLA on. Before **RENT**, set **Reliability target** again. If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). +CLI and API search only **quote** SLA pricing—they do not turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT** (search filters do not carry over to rent). If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b95b38c7..86af0128 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -35,7 +35,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. 2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. -3. Verify under **Instances**; after UTC settlement, check credits in **Account → Billing**. +3. Verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#in-the-web-console)). After UTC settlement, check credits in **Account → Billing**. **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -126,9 +126,11 @@ Search **quotes** SLA pricing. The SLA starts only when you set **Reliability ta **Console-only:** You can stop here. SLA rental in the web console does not require CLI or API keys. Continue below only if you automate search or rent. -### Search filters +### Search filters (console and programmatic search) -| Filter | Meaning | Example | +Console controls use the same concepts; they do not accept CLI query strings. Use the left **Search filters** bar for console rentals. The **Example (CLI / API)** column is for `vastai search offers` and REST only. + +| Filter | Meaning | Example (CLI / API) | | --- | --- | --- | | `target_reliability` | Your desired reliability level. Also drives SLA charge calculation and ranking. | `target_reliability=0.95` | | `has_sla` | Restrict to offers with (or without) SLA enabled. | `has_sla=true` | @@ -225,7 +227,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -CLI search defaults include `external=false` and `rented=false`; include those keys on REST so quotes match CLI. +CLI search defaults are `external=false rentable=true verified=true` (see [search offers](/cli/reference/search-offers)). Include those keys on REST so quotes match CLI. Add `rented=false` only when you want to exclude rented machines (not part of the CLI default query string). **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: @@ -305,7 +307,7 @@ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** be When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA charge line or `dph_total`. Host confidence is not shown in the client UI and is not a setting you control. +1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA charge line or `dph_total`. Host confidence is not shown in the web console and is not a setting you control. 2. **Daily billing** — you pay compute plus the SLA charge each day. 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA charge with no credit. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 9bad45b8..f0b42bd5 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -146,7 +146,7 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ **If you only read three fields:** Check `has_data` (widen dates if `false`), then `summary.worst_day_loss`, then `summary.total_sla`. -A successful response looks like this (fields abbreviated): +A successful response looks like this (fields abbreviated; counts are illustrative—`covered_days` and `skipped_days` need not be equal): ```json { @@ -155,8 +155,8 @@ A successful response looks like this (fields abbreviated): "has_data": true, "start_day": 19723, "end_day": 19812, - "covered_days": 45, - "skipped_days": 45, + "covered_days": 60, + "skipped_days": 30, "reliability": 0.998500, "fleet_reliability": 0.991200, "params": { @@ -293,16 +293,20 @@ For missing or invalid API keys and permission denials (`machine_read`), see [Au Optional. Skip this section unless you automate many machines. Console hosts can use **Set Pricing → SLA** and a single request instead of the loop below. +**Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). + ```bash export VAST_API_KEY="YOUR_API_KEY" ``` 1. List machine IDs: `vastai show machines -q` (numeric IDs only) or `vastai show machines --raw | jq -r '.machines[].id'`. -2. Run backtests **sequentially** (one machine at a time). Set `r` to each machine’s **candidate** reliability commitment (the `sla_r_claim` you plan to list)—do not assume a fleet-wide `0.95` if you intend to list at `0.99` or another value: +2. Run backtests **sequentially** (one machine at a time). Set `r` to each machine’s **candidate** reliability commitment (the `sla_r_claim` you plan to list)—do not assume a fleet-wide `0.95` if you intend to list at `0.99` or another value. Write responses under a private temp dir (not world-readable `/tmp` paths on shared hosts) and delete them when done: ```bash # Prefer each machine's planned sla_r_claim / sla_sigma_x from show machines --raw. # Uniform r override: export R=0.99. Map sla_sigma_x → p via Confidence values table. +BT_DIR=$(mktemp -d) +trap 'rm -rf "$BT_DIR"' EXIT machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do r="${R:-}" @@ -324,16 +328,17 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do | if $s <= 0.35 then 0.83 elif $s <= 0.75 then 0.6667 else 0.50 end') - http=$(curl -s -o /tmp/sla_bt_$id.json -w "%{http_code}" \ + out="$BT_DIR/sla_bt_$id.json" + http=$(curl -s -o "$out" -w "%{http_code}" \ -H "Authorization: Bearer $VAST_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$r&p=$p") - if [ "$http" != "200" ] || ! jq -e '.success == true' /tmp/sla_bt_$id.json >/dev/null 2>&1; then - echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' /tmp/sla_bt_$id.json 2>/dev/null)" + if [ "$http" != "200" ] || ! jq -e '.success == true' "$out" >/dev/null 2>&1; then + echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' "$out" 2>/dev/null)" sleep 2; continue fi jq -c --arg id "$id" --argjson r "$r" --argjson p "$p" \ '{machine_id: $id, r: $r, p: $p, worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' \ - /tmp/sla_bt_$id.json + "$out" sleep 2 done ``` @@ -353,5 +358,5 @@ Expect roughly two seconds per machine minimum (`sleep 2` plus request time). Fo - [SLA Backtest API](/api-reference/host/sla-backtest) — formal API reference for this endpoint - [SLA Offers](/host/sla-offers) — listing parameters, economics, and risk scenarios -- [SLA (clients)](/guides/instances/choosing/sla-coverage) — how renters choose targets and read `dph_total` +- [SLA (renters)](/guides/instances/choosing/sla-coverage) — how renters (clients) choose targets and read `dph_total` - [API permissions](/api-reference/permissions) — `machine_read` scope required diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index fa80dbd7..08b4c935 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -9,7 +9,7 @@ Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listi This page explains how SLA offers work from the host side — what you set, how clients choose an SLA, and what happens when uptime is good or bad. -SLA settlement is **asymmetric by design**: when reliability is strong relative to the client's target, you keep the SLA charge; when it falls short, client credits can exceed the charge you collected that day. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). +SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; on bad days, service credits can exceed the fees you collected. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). @@ -40,7 +40,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. 6. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). -7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. Verify in search (`machine_id=` filter). +7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. Verify in search with `has_sla=true`, your commitment as `expected_reliability`, and a sample `target_reliability` (for example `machine_id=12345 has_sla=true expected_reliability>=0.99 target_reliability=0.95`). ## Before you enable SLA @@ -345,7 +345,7 @@ This loop does not turn an SLA on for new machines. Enable an SLA on each machin -Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. +Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. Expired offers (past `end_date`) are skipped so a re-list run does not unpublish live SLA listings. **Before fleet SLA rollout:** @@ -385,6 +385,10 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -z "$price" ] || [ -z "$end" ] || [ -z "$chunk" ]; then echo "skip $id: missing price_gpu/end_date/min_chunk"; continue fi + now=$(date -u +%s) + if ! jq -n --argjson end "$end" --argjson now "$now" '$end > $now' >/dev/null 2>&1; then + echo "skip machine_id=$id: end_date expired"; continue + fi # Opt-in only: skip machines with no positive reliability commitment (do not invent 0.99) if ! echo "$machine" | jq -e '(.sla_r_claim // 0) > 0' >/dev/null; then echo "skip $id: no positive sla_r_claim (enable SLA per machine first)"; continue @@ -402,7 +406,12 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do -H "Authorization: Bearer $VAST_API_KEY" \ -H "Content-Type: application/json" \ -d "$body") - echo "machine_id=$id response: $resp" + ok=$(echo "$resp" | jq -r '.success // empty') + if [ "$ok" = "true" ]; then + echo "machine_id=$id ok" + else + echo "machine_id=$id error: $(echo "$resp" | jq -c '{success,error,msg}' 2>/dev/null || echo "$resp")" + fi sleep 2 done ``` @@ -708,7 +717,7 @@ Do **not** compare `last_days=7` totals to single-day `worst_day_loss` from the | `per_machine[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | | Fleet `per_day[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | -- `{user_id}` — Your account ID (from **Account → Profile** in the console, or `vastai show user`). +- `{user_id}` — Replace with your account ID from **Account → Profile** in the console, or `vastai show user` (do not leave the curly-brace placeholder in the URL). - Settlement is evaluated on UTC day boundaries. Rows typically update within a few hours after UTC midnight. ## Tips for competitive SLA offers From 131877a8913f5401173d23ddeeeab5ca0260b41a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:40:32 -0700 Subject: [PATCH 130/250] docs(sla): address doc-review consensus (cycle 82) Align REST search defaults with CLI, clarify console verify vs billing, and fix Tight/p label plus relative backtester dates. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 6 +++--- host/sla-backtester.mdx | 13 +++++++------ host/sla-offers.mdx | 8 ++++---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 86af0128..68c5bb62 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -35,7 +35,8 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. 2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. -3. Verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#in-the-web-console)). After UTC settlement, check credits in **Account → Billing**. +3. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#in-the-web-console)). +4. After the prior UTC day has settled, check credits in **Account → Billing** (see [Settlement timing](#settlement-timing)). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -218,7 +219,6 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ "verified": {"eq": true}, "rentable": {"eq": true}, "external": {"eq": false}, - "rented": {"eq": false}, "allocated_storage": 50, "order": [["dph_total", "asc"]], "target_reliability": {"eq": 0.95}, @@ -227,7 +227,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -CLI search defaults are `external=false rentable=true verified=true` (see [search offers](/cli/reference/search-offers)). Include those keys on REST so quotes match CLI. Add `rented=false` only when you want to exclude rented machines (not part of the CLI default query string). +CLI search defaults are `external=false rentable=true verified=true` (see [search offers](/cli/reference/search-offers)). The body above matches those filters; add `"rented": {"eq": false}` only when you intentionally exclude rented slots. **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index f0b42bd5..967b1c15 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -115,12 +115,13 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ Custom date range (optional — Jan–Apr 2024 for illustration): ```bash -# start_date = Jan 1, 2024 UTC; end_date = Apr 1, 2024 UTC -# Linux: date -u -d '2024-01-01' +%s -# macOS: date -u -j -f '%Y-%m-%d' '2024-01-01' +%s -# On Windows, use WSL or an online epoch converter. +# Example window: last ~90 days ending now +# Linux: start=$(date -u -d '90 days ago' +%s); end=$(date -u +%s) +# macOS: start=$(date -u -v-90d +%s); end=$(date -u +%s) +start=$(date -u -d '90 days ago' +%s) +end=$(date -u +%s) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667&start_date=1704067200&end_date=1711929600" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667&start_date=$start&end_date=$end" ``` Compare two confidence levels on the same history: @@ -130,7 +131,7 @@ Compare two confidence levels on the same history: curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667" -# High confidence (~83%) — tighter spread, lower simulated SLA charges +# Tight (~83%) — tighter spread, lower simulated SLA charges curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.83" ``` diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 08b4c935..1bb37ffb 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -38,9 +38,9 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 2. Test on a [separate client account](/host/hosting-overview#testing-your-own-machine) (billed like any rental). 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). -5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. +5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. Before your first SLA rental, read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. 6. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). -7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. Verify in search with `has_sla=true`, your commitment as `expected_reliability`, and a sample `target_reliability` (for example `machine_id=12345 has_sla=true expected_reliability>=0.99 target_reliability=0.95`). +7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. **Optional CLI/API:** search with `has_sla=true`, your commitment as `expected_reliability`, and a sample `target_reliability` (for example `machine_id=12345 has_sla=true expected_reliability>=0.99 target_reliability=0.95`). ## Before you enable SLA @@ -237,7 +237,7 @@ If the machine is already **listed**: - **Search:** `dph_total` includes the SLA charge at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). -In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same as pressing **LIST** or running `vastai list machine`), not a save-only draft. +In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same publish step as **LIST**; SLA parameters require this REST body or **Set Pricing → SLA**, not `vastai list machine` flags). #### Web console SLA preview @@ -730,7 +730,7 @@ Do **not** compare `last_days=7` totals to single-day `worst_day_loss` from the ## Related documentation -- [SLA (clients)](/guides/instances/choosing/sla-coverage) — how renters find and evaluate SLA offers +- [SLA (renters)](/guides/instances/choosing/sla-coverage) — how renters find and evaluate SLA offers - [SLA Earnings Backtester](/host/sla-backtester) — preview SLA economics on historical earnings - [Hosting Overview](/host/hosting-overview) — offers, rental contracts, and listing basics - [Understanding Verification](/host/understanding-verification) — platform verification (separate from SLA, but related to trust) From ec5d0a79fb4d23f74c49c5ed4a5a5073bafca7a2 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:44:07 -0700 Subject: [PATCH 131/250] docs(sla): address doc-review consensus (cycle 83) Fix post-rent verify anchors, add --storage to host verify examples, and link overview to checklist/risk. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 9 +++++---- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 6 +++--- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 2870498d..4c888a97 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -166,7 +166,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings. Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | -| Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key) | +| Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=… verified=any has_sla=true …'` (`verified=any` is often required when checking your own machine). | Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 68c5bb62..d8fbad9b 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -35,7 +35,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. 2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. -3. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#in-the-web-console)). +3. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). 4. After the prior UTC day has settled, check credits in **Account → Billing** (see [Settlement timing](#settlement-timing)). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -145,10 +145,11 @@ Console controls use the same concepts; they do not accept CLI query strings. Us ```bash # SLA offers where the host's reliability commitment is at least 99% -vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' +# Set --storage to match the disk you will rent (console often 10; REST often 8+) +vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10 # Compare total cost including SLA charge -vastai search offers 'has_sla=true target_reliability=0.95 num_gpus=1' --order dph_total +vastai search offers 'has_sla=true target_reliability=0.95 num_gpus=1' --storage 10 --order dph_total ``` When you set `target_reliability`, search results include: @@ -366,7 +367,7 @@ Production settlement uses the multi-window reliability blend described above, n ## Viewing SLA on active instances -### In the web console +### In the web console (active instances) 1. Open **Instances** and select your running instance. 2. Open **price details** (or the instance billing panel) and confirm an **SLA charge** line is present. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 5d034fc9..bbc267bc 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -49,7 +49,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (uptime guarantee):** Optional add-on for on-demand listings. In short: you state a reliability **commitment**, the renter picks a **target**, they pay a small extra hourly fee, and if uptime misses that target they get a credit from your earnings. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language), then the [economics walkthrough](/host/sla-offers#economics-walkthrough) before enabling SLA. Renters: [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). In renter-facing docs, **renter** means the same role as **client** (the person renting your machine). +- **SLA (uptime guarantee):** Optional add-on for on-demand listings. In short: you state a reliability **commitment**, the renter picks a **target**, they pay a small extra hourly fee, and if uptime misses that target they get a credit from your earnings. Start with the [SLA host checklist](/host/sla-offers#sla-host-checklist), then [Before you enable SLA](/host/sla-offers#before-you-enable-sla), [Billing vs settlement](/host/sla-offers#billing-vs-settlement-important), and [Risk scenarios](/host/sla-offers#risk-scenarios) before your first SLA listing. For plain language and economics, see [SLA in plain language](/host/sla-offers#sla-in-plain-language) and the [economics walkthrough](/host/sla-offers#economics-walkthrough). Renters: [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). In renter-facing docs, **renter** means the same role as **client** (the person renting your machine). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 967b1c15..f131fa53 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -112,7 +112,7 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667" ``` -Custom date range (optional — Jan–Apr 2024 for illustration): +Custom date range (optional — relative UTC window): ```bash # Example window: last ~90 days ending now diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1bb37ffb..66b8987f 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -40,7 +40,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. Before your first SLA rental, read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. 6. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). -7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. **Optional CLI/API:** search with `has_sla=true`, your commitment as `expected_reliability`, and a sample `target_reliability` (for example `machine_id=12345 has_sla=true expected_reliability>=0.99 target_reliability=0.95`). +7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. **Optional CLI/API:** search with `--storage` matching how renters quote (for example `vastai search offers 'machine_id=12345 has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). ## Before you enable SLA @@ -498,10 +498,10 @@ When SLA is enabled on an offer, clients see: **Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the reliability commitment. The published reliability commitment appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, use `has_sla=true` or filter on `expected_reliability > 0`; do not use the `reliability` filter as an SLA selector. -Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand): +Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand). Match disk allocation before comparing `dph_total` across channels (CLI default is often 5 GiB; console Search is typically 10 GB; REST examples often use 8 GB `allocated_storage`): ```bash -vastai search offers 'machine_id=12345 verified=any has_sla=true target_reliability=0.95' --raw \ +vastai search offers 'machine_id=12345 verified=any has_sla=true target_reliability=0.95' --storage 10 --raw \ | jq '[.offers[] | select(.is_bid == false) | {id, num_gpus, dph_total, expected_reliability, reliability}]' ``` From ae7273e0e4457eeaf625cb930fcf8c890d674516 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:47:31 -0700 Subject: [PATCH 132/250] docs(sla): address doc-review consensus (cycle 84) Align fleet 429 prose with illustrative scripts, clarify REST earnings params, and fix host self-verify / permissions framing. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 ++-- cli/reference/search-offers.mdx | 3 ++- cli/reference/show-earnings.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 10 ++++++++-- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 4c888a97..bcea90ca 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -17,7 +17,7 @@ Use this page for scoped API keys and automation. If you only use the web consol On this page, **renter** means client and **host** means provider. API names may still say client or provider. -The sections below define permission categories and JSON recipes for renter and host SLA workflows. +The sections below define permission categories and JSON recipes. Categories and endpoint lists apply **platform-wide** (templates, serverless, teams, and other automation)—not only SLA. The SLA recipes are optional shortcuts for that workflow. For an overview of API key creation and usage, see [Authentication](/api-reference/authentication). @@ -166,7 +166,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings. Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | -| Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=… verified=any has_sla=true …'` (`verified=any` is often required when checking your own machine). | +| Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=12345 verified=any has_sla=true target_reliability=0.95' --storage 10` (`verified=any` is often required when checking your own machine). | Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 0e25e4d1..5bcc052c 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -80,7 +80,8 @@ Filter examples (including SLA quotes) are under [Examples](#examples). Query sy ```bash # Marketplace reliability score (not SLA commitment) -vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=False' +# rented=false is optional (excludes slots you already rent); not part of the CLI default query +vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=false' # SLA search quote (enable the SLA at rent via console/REST — see SLA) # Always set --storage explicitly when comparing dph_total (CLI default 5 GiB ≠ REST 8 GB). diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index 1522bf02..1929f5c6 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -37,7 +37,7 @@ vastai show earnings [OPTIONS] Machine id (optional) (alias: `--machine_id`) -`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). For one machine / one UTC day, see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). +`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). CLI `--start_date` / `--end_date` are calendar convenience; for REST-only query params `last_days`, `sday`, and `eday` (for example `last_days=1` polling or exact UTC day index), see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing) or [Show Earnings](/api-reference/billing/show-earnings). ## Examples diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index f131fa53..0d91def6 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -344,7 +344,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Expect roughly two seconds per machine minimum (`sleep 2` plus request time). For 50 machines, budget at least a few minutes. Run off-peak before a fleet SLA rollout. On `429`, back off per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). Parallel requests are not recommended unless you implement backoff. +Expect roughly two seconds per machine minimum (`sleep 2` plus request time). For 50 machines, budget at least a few minutes. Run off-peak before a fleet SLA rollout. This example logs failure and continues after one attempt; on HTTP **429**, wait and retry that machine with backoff before treating it as failed—a single burst can otherwise skip healthy machines. Parallel requests are not recommended unless you implement backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). 3. Compare `worst_day_loss` and `total_sla` across machines at the **`r` each will list** (or at one shared `R` if the fleet is uniform). 4. Apply matching `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 66b8987f..a689db4b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -6,6 +6,8 @@ description: "Offer an SLA on your machines: set a reliability commitment and co Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose an SLA pay a small hourly **SLA charge** included in **`dph_total`** (dollars per hour total in search — base compute plus SLA charge), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. +**New to SLA?** Read [SLA in plain language](#sla-in-plain-language) first, then return here for economics and API detail. + This page explains how SLA offers work from the host side — what you set, how clients choose an SLA, and what happens when uptime is good or bad. @@ -40,7 +42,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. Before your first SLA rental, read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. 6. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). -7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. **Optional CLI/API:** search with `--storage` matching how renters quote (for example `vastai search offers 'machine_id=12345 has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). +7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. **Optional CLI/API:** search with `--storage` matching how renters quote. If you search your own machine and see no rows, add `verified=any` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). ## Before you enable SLA @@ -357,11 +359,13 @@ For multiple machines, loop sequentially — do not parallelize without backoff: 1. Skip machines missing base pricing fields. 2. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields (preserve existing reliability commitment and confidence when set). -3. On `429`, sleep and retry with exponential backoff. +3. Space requests (`sleep 2` in the example). At fleet scale, detect HTTP **429** and retry that machine with backoff before treating it as failed—do not rerun the whole loop with `DRY_RUN=0` until transient rate limits clear. 4. On `invalid_sla_params`, `sla_not_approved`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. +This example is illustrative: it sleeps between machines and logs success/error from JSON, but does not implement full HTTP 429 retry. Add status checks and backoff before production fleet rollouts. + ```bash export VAST_API_KEY="YOUR_API_KEY" # Leave DRY_RUN=1 until you confirm each machine is **Listed** (or on your allowlist). @@ -684,6 +688,8 @@ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA sett **Quick rules:** - **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs backtester `worst_day_loss`), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` for that calendar day. Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +Replace `{user_id}` below with your account ID from **Account → Profile**, or set `USER_ID=$(vastai show user --raw | jq -r '.id')` and substitute `$USER_ID` in the URL. + ```bash # Exact UTC day 2026-07-24 for machine 12345 (sday/eday = 20658) curl -s -H "Authorization: Bearer $VAST_API_KEY" \ From da4ac83eff162e2d42078b54f48a4b1019d3327e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:54:04 -0700 Subject: [PATCH 133/250] docs(sla): address doc-review consensus (cycle 85) Merge duplicate invalid_args rows, clarify REST vs CLI rented defaults, and tighten host/renter recipe routing. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 6 ++++-- host/sla-offers.mdx | 5 ++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index bcea90ca..b9a515f4 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -93,7 +93,7 @@ You can create scoped keys using: **Renter — search and REST rent.** -**Renter automation:** Search with `has_sla` → rent with `target_reliability` on `PUT /api/v0/asks/{id}/` → verify with `GET /api/v1/instances/`. Hosts: use the **Host — list, backtest, and earnings** recipe below. +**Renter automation:** Search with `has_sla` → rent with `target_reliability` on `PUT /api/v0/asks/{id}/` → verify with `GET /api/v1/instances/`. **If you are a host, do not use this JSON** — use the [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe). Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d8fbad9b..593578cb 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -228,7 +228,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -CLI search defaults are `external=false rentable=true verified=true` (see [search offers](/cli/reference/search-offers)). The body above matches those filters; add `"rented": {"eq": false}` only when you intentionally exclude rented slots. +CLI search defaults are `external=false rentable=true verified=true` (see [search offers](/cli/reference/search-offers)). The body above matches those three filters. REST `POST /api/v0/bundles/` may default omitted `rented` to `{"eq": false}` per [Search Offers OpenAPI](/api-reference/search/search-offers)—that is **not** the same as the CLI default query (which does not send `rented`). Pass `rented` explicitly when you need a specific filter; do not assume omitted `rented` on REST matches CLI. **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: @@ -290,6 +290,8 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | | Too many requests | HTTP 429 | Wait and back off. Before retrying the same `PUT`, confirm with `GET /api/v1/instances/` whether the contract already exists. If retry returns `invalid_price`, `no_such_ask`, 404, or 410, re-search with the same `target_reliability` and storage, then rent a fresh offer id. | +| Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | +| Forbidden / wrong account | HTTP 403 | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | | SLA with a bid or interruptible offer | Rent does not turn on an SLA | Search with `"type": "ondemand"`. Do not send `price` or `bid_price` when you want an SLA. | | Channel | Default storage | Field | Units (label) | @@ -431,7 +433,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta **Console:** After UTC settlement, open **Account → Billing** and look for **service credit** or SLA credit line items (wording can vary)—not in the instance price panel. Credits are not available via the Charges API, invoices, or billing exports today. -**API:** Prefer **Account → Billing** for service credit reconciliation. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. `GET /api/v1/invoices/` covers payment transactions (top-ups, transfers, payouts), not SLA service-credit line items. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. +**API integrators:** Prefer **Account → Billing** for service credit reconciliation. There is no renter API for SLA credits. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. `GET /api/v1/invoices/` covers payment transactions (top-ups, transfers, payouts), not SLA service-credit line items. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. ## Related documentation diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a689db4b..43b6c095 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -36,7 +36,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist -1. Complete [host setup](https://cloud.vast.ai/host/setup/) and confirm the machine appears on **Host → Machines** (healthy, priced). If you want SLA from the first rental, finish **Set Pricing → SLA** before your first **LIST** (see [Web console](#web-console)). +1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account** (do not host from a renter-only account), then [host setup](https://cloud.vast.ai/host/setup/) and confirm the machine appears on **Host → Machines** (healthy, priced). If you want SLA from the first rental, finish **Set Pricing → SLA** before your first **LIST** (see [Web console](#web-console)). 2. Test on a [separate client account](/host/hosting-overview#testing-your-own-machine) (billed like any rental). 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). @@ -442,11 +442,10 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | --- | --- | --- | | 401 | `success: false` + `msg` (+ optional `error`) | Missing `machine_write` or other required permission | | 403 | `machine_locked` | Machine is decommissioned or migration-locked | -| 400 | `invalid_args` | Machine ID not found for your account (includes other hosts' machines) | +| 400 | `invalid_args` | Machine ID not found for your account, or malformed / incompatible request body | | 400 | `invalid_sla_params` | SLA parameters failed validation | | 400 | `sla_not_approved` | Host account is not approved to create SLA asks | | 400 | `sla_daemon_outdated` | Machine daemon build is too old for SLA listing | -| 400 | `invalid_args` | Malformed or incompatible request body | **`machine_locked`:** Returned when a machine is decommissioned or migration-locked. If you are migrating hardware, finish or cancel active rentals first, remove or update the listing as needed, and contact support if the machine remains locked. Existing SLA terms on active contracts remain in force until those contracts end. From 647bd9f3399f3dc6b25d7d3874819935d133d6e6 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:57:30 -0700 Subject: [PATCH 134/250] docs(sla): address doc-review consensus (cycle 86) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix permissions/search-offers ≥3/8 nits, surface host SLA early, and move earnings curls out of Warning. Co-authored-by: Cursor --- api-reference/permissions.mdx | 6 ++---- cli/reference/search-offers.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 2 +- host/hosting-overview.mdx | 4 +++- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 18 +++++++++++------- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b9a515f4..1ac3d4e0 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -91,9 +91,7 @@ You can create scoped keys using: -**Renter — search and REST rent.** - -**Renter automation:** Search with `has_sla` → rent with `target_reliability` on `PUT /api/v0/asks/{id}/` → verify with `GET /api/v1/instances/`. **If you are a host, do not use this JSON** — use the [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe). +**Renter — search and REST rent.** Search with `has_sla` → rent with `target_reliability` on `PUT /api/v0/asks/{id}/` → verify with `GET /api/v1/instances/`. **If you are a host, do not use this JSON** — use the [Host SLA scoped-key recipe](#host-sla-scoped-key-recipe). Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. @@ -165,7 +163,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA** → **Save**. First publish: **Save** → **LIST**. Already listed: **Save** only ([Web console](/host/sla-offers#web-console)) | | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | -| Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings. Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | +| Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings (console billing needs no API key; API earnings need `billing_read`). Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | | Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=12345 verified=any has_sla=true target_reliability=0.95' --storage 10` (`verified=any` is often required when checking your own machine). | Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 5bcc052c..c7cf8867 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -53,7 +53,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] - Experimental search path — not recommended for production use. Prefer the default search for SLA filtering. + Experimental search path. Behavior and SLA fields may differ from the default search—not recommended for SLA automation or production. Prefer the default search for SLA filtering and `dph_total` quotes. @@ -65,7 +65,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] - Comma-separated list of fields to sort on. postfix field with - to sort desc. ex: -o 'num_gpus,total_flops-'. default='score-' (alias: `--order`) + Comma-separated list of fields to sort on. Postfix the field name with `-` to sort descending (for example, `-o 'num_gpus,total_flops-'`). Default: `score-` (alias: `--order`) ## Description diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 593578cb..b3c430fb 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -34,7 +34,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) has credit or a payment method, and pick a [template](/guides/instances/choosing/templates) in Search (see [Finding & Renting](/guides/instances/choosing/find-and-rent)). 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. -2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. +2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Before **RENT**, add an SSH key to your account (or choose a Jupyter/notebook template that does not require SSH). Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. 3. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). 4. After the prior UTC day has settled, check credits in **Account → Billing** (see [Settlement timing](#settlement-timing)). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index bbc267bc..c3597390 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -7,6 +7,8 @@ description: "Set up hosting on Vast.ai: accounts, machines, offers, maintenance **Looking to rent GPUs?** See [Finding & Renting Instances](/guides/instances/choosing/find-and-rent) and [SLA](/guides/instances/choosing/sla-coverage). + +**Offering an SLA?** Optional on-demand uptime guarantee—read economics and risk before you enable it. Start with the [SLA host checklist](/host/sla-offers#sla-host-checklist) and [Before you enable SLA](/host/sla-offers#before-you-enable-sla). Vast is a GPU marketplace. Hosts sell GPU resources on the marketplace. Hosts are responsible for: @@ -49,7 +51,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (uptime guarantee):** Optional add-on for on-demand listings. In short: you state a reliability **commitment**, the renter picks a **target**, they pay a small extra hourly fee, and if uptime misses that target they get a credit from your earnings. Start with the [SLA host checklist](/host/sla-offers#sla-host-checklist), then [Before you enable SLA](/host/sla-offers#before-you-enable-sla), [Billing vs settlement](/host/sla-offers#billing-vs-settlement-important), and [Risk scenarios](/host/sla-offers#risk-scenarios) before your first SLA listing. For plain language and economics, see [SLA in plain language](/host/sla-offers#sla-in-plain-language) and the [economics walkthrough](/host/sla-offers#economics-walkthrough). Renters: [SLA in plain language](/guides/instances/choosing/sla-coverage#sla-in-plain-language). In renter-facing docs, **renter** means the same role as **client** (the person renting your machine). +- **SLA (optional):** On-demand uptime guarantee; configure under **Set Pricing → SLA**. Start here: [SLA host checklist](/host/sla-offers#sla-host-checklist). Renters: [SLA](/guides/instances/choosing/sla-coverage). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 0d91def6..d9426fc2 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -115,7 +115,7 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ Custom date range (optional — relative UTC window): ```bash -# Example window: last ~90 days ending now +# Example window: last ~90 days ending now (Linux GNU date) # Linux: start=$(date -u -d '90 days ago' +%s); end=$(date -u +%s) # macOS: start=$(date -u -v-90d +%s); end=$(date -u +%s) start=$(date -u -d '90 days ago' +%s) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 43b6c095..c958ed57 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -67,7 +67,7 @@ On outage days you may still bill clients for **intended** compute **and** owe s -**Rental types:** The SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible rentals are not covered by the SLA, even on machines that offer SLA on on-demand. On-demand contracts on the same machine can have an SLA. Reserved or prepay attempts on an offer with an SLA are not supported — use on-demand to rent with an SLA. +**Rental types:** The SLA applies to **on-demand rentals only**. It does not apply to interruptible/bid instances or reserved/prepay rentals. Interruptible rentals are not covered by the SLA, even on machines that offer an SLA for on-demand rentals. On-demand contracts on the same machine can have an SLA. Reserved or prepay attempts on an offer with an SLA are not supported — use on-demand to rent with an SLA. - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. @@ -686,24 +686,28 @@ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA sett **Quick rules:** - **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs backtester `worst_day_loss`), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` for that calendar day. Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +- **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window. + + +Replace `{user_id}` / use `USER_ID` from **Account → Profile**, or: -Replace `{user_id}` below with your account ID from **Account → Profile**, or set `USER_ID=$(vastai show user --raw | jq -r '.id')` and substitute `$USER_ID` in the URL. +```bash +USER_ID=$(vastai show user --raw | jq -r '.id') +``` ```bash # Exact UTC day 2026-07-24 for machine 12345 (sday/eday = 20658) curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?machid=12345&sday=20658&eday=20658" \ + "https://console.vast.ai/api/v0/users/${USER_ID}/machine-earnings/?machid=12345&sday=20658&eday=20658" \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` -- **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window: - ```bash +# Fleet snapshot (last_days=1 — coarse, not a settled calendar day) curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?last_days=1" \ + "https://console.vast.ai/api/v0/users/${USER_ID}/machine-earnings/?last_days=1" \ | jq '.per_machine[] | {machine_id, sla_earn}' ``` - **Machine-scoped coarse poll (`last_days=1`, not a settled calendar day):** From a1a97ff5d81439152dbeb2fbbaed641157983a1d Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 11:57:35 -0700 Subject: [PATCH 135/250] docs(sla): use USER_ID in remaining machine-earnings curl (cycle 86) Co-authored-by: Cursor --- host/sla-offers.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index c958ed57..7dc3d548 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -713,7 +713,7 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ ```bash curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/users/{user_id}/machine-earnings/?machid=12345&last_days=1" \ + "https://console.vast.ai/api/v0/users/${USER_ID}/machine-earnings/?machid=12345&last_days=1" \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` From 6b0438ce821e9c109c10e6e2b3efe5ed7591a6a9 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 15:48:43 -0700 Subject: [PATCH 136/250] docs(sla): address doc-review consensus (cycle 87) Fix USER_ID sourcing for billing_read keys, link checklist verify to jq filter, and add Destroy guidance for stuck rentals. Co-authored-by: Cursor --- guides/instances/choosing/find-and-rent.mdx | 2 ++ guides/instances/choosing/sla-coverage.mdx | 5 +++-- host/sla-backtester.mdx | 14 +++++++------- host/sla-offers.mdx | 6 +++--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 222ea045..716633a4 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -114,3 +114,5 @@ Startup time depends on the template and is usually under 5 minutes. If waiting - Try a different machine - Note: You're not charged while instances are loading - With slow internet and large images, downloads can take an hour or more + +If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy** to stop ongoing compute charges (stopping alone may not end all billing—see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage) when you used an SLA). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b3c430fb..2a6d9814 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -34,9 +34,10 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) has credit or a payment method, and pick a [template](/guides/instances/choosing/templates) in Search (see [Finding & Renting](/guides/instances/choosing/find-and-rent)). 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. -2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Before **RENT**, add an SSH key to your account (or choose a Jupyter/notebook template that does not require SSH). Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. +2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Before **RENT**, add an SSH key under **Account → Keys** (or choose a Jupyter/notebook template that does not require SSH)—see [Keys](/guides/reference/keys). Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. 3. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). -4. After the prior UTC day has settled, check credits in **Account → Billing** (see [Settlement timing](#settlement-timing)). +4. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing**. +5. When you are finished, **Destroy** the instance (not only **Stop**) to end ongoing charges—see [If your instance goes down](#if-your-instance-goes-down). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index d9426fc2..6d4e3de0 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -77,7 +77,7 @@ The backtester is available through the REST API only. You must own the machine ``` -GET /api/v0/host/sla_backtest/ +GET /api/v0/host/sla_backtest ``` Requires Bearer authentication. This endpoint is rate-limited like other host API endpoints — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) for retry guidance. @@ -109,7 +109,7 @@ Minimal baseline (default 90-day lookback — no custom dates required): ```bash curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667" + "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.95&p=0.6667" ``` Custom date range (optional — relative UTC window): @@ -121,7 +121,7 @@ Custom date range (optional — relative UTC window): start=$(date -u -d '90 days ago' +%s) end=$(date -u +%s) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667&start_date=$start&end_date=$end" + "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.95&p=0.6667&start_date=$start&end_date=$end" ``` Compare two confidence levels on the same history: @@ -129,18 +129,18 @@ Compare two confidence levels on the same history: ```bash # Normal confidence (~67%, default 0.6667) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667" + "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.99&p=0.6667" # Tight (~83%) — tighter spread, lower simulated SLA charges curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.83" + "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.99&p=0.83" ``` Stress-test with flat 90% uptime: ```bash curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667&reliability=0.90" + "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.99&p=0.6667&reliability=0.90" ``` ## Reading the response @@ -332,7 +332,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do out="$BT_DIR/sla_bt_$id.json" http=$(curl -s -o "$out" -w "%{http_code}" \ -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$r&p=$p") + "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=$id&r=$r&p=$p") if [ "$http" != "200" ] || ! jq -e '.success == true' "$out" >/dev/null 2>&1; then echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' "$out" 2>/dev/null)" sleep 2; continue diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 7dc3d548..250fbb6a 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -42,7 +42,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. Before your first SLA rental, read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. 6. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). -7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. **Optional CLI/API:** search with `--storage` matching how renters quote. If you search your own machine and see no rows, add `verified=any` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). +7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. **Optional CLI/API:** search with `--storage` matching how renters quote. If you search your own machine and see no rows, add `verified=any` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). On sliced machines, search may return multiple rows (bid vs on-demand, different `num_gpus`); filter on-demand offers with the jq example in [Search / client-visible fields](#search--client-visible-fields). ## Before you enable SLA @@ -689,10 +689,10 @@ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA sett - **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window. -Replace `{user_id}` / use `USER_ID` from **Account → Profile**, or: +Replace `{user_id}` with your account ID from **Account → Profile** (preferred for `billing_read`-only keys). Optional CLI: `USER_ID=$(vastai show user --raw | jq -r '.id')` — that needs `user_read` if `show user` is denied; see [Host SLA scoped-key recipe](/api-reference/permissions#host-sla-scoped-key-recipe). ```bash -USER_ID=$(vastai show user --raw | jq -r '.id') +USER_ID=YOUR_USER_ID # from Account → Profile ``` ```bash From b022b5ed6777f6a77ad006e5274a0526e8da6022 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 15:51:37 -0700 Subject: [PATCH 137/250] docs(sla): address doc-review consensus (cycle 88) Gate first LIST until checklist step 7, split console vs CLI verify, and align Profile-first user_id guidance. Co-authored-by: Cursor --- host/sla-offers.mdx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 250fbb6a..d524f877 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -4,7 +4,7 @@ description: "Offer an SLA on your machines: set a reliability commitment and co "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose an SLA pay a small hourly **SLA charge** included in **`dph_total`** (dollars per hour total in search — base compute plus SLA charge), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose an SLA pay a small hourly **SLA charge** included in **`dph_total`** (dollars per hour total in search — GPU + storage + SLA charge), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. **New to SLA?** Read [SLA in plain language](#sla-in-plain-language) first, then return here for economics and API detail. @@ -36,13 +36,15 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist -1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account** (do not host from a renter-only account), then [host setup](https://cloud.vast.ai/host/setup/) and confirm the machine appears on **Host → Machines** (healthy, priced). If you want SLA from the first rental, finish **Set Pricing → SLA** before your first **LIST** (see [Web console](#web-console)). +1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account** (do not host from a renter-only account), then [host setup](https://cloud.vast.ai/host/setup/) and confirm the machine appears on **Host → Machines** (healthy, priced). Configure **Set Pricing → SLA** (reliability commitment, confidence, and related fields) if you want SLA from the first rental—but do **not** press **LIST** to go live until you complete steps 2–6; step 7 is your first publish and verify. 2. Test on a [separate client account](/host/hosting-overview#testing-your-own-machine) (billed like any rental). 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. Before your first SLA rental, read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. 6. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). -7. Enable SLA listing: **Save** pricing, then click **LIST** on a first publish. If the machine is already listed, **Save** alone updates the live offer. **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. **Optional CLI/API:** search with `--storage` matching how renters quote. If you search your own machine and see no rows, add `verified=any` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). On sliced machines, search may return multiple rows (bid vs on-demand, different `num_gpus`); filter on-demand offers with the jq example in [Search / client-visible fields](#search--client-visible-fields). +7. **First publish and verify:** **Save** pricing, then click **LIST** (first publish only). If the machine is already listed, **Save** alone updates the live offer. + - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. + - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). ## Before you enable SLA @@ -726,7 +728,7 @@ Do **not** compare `last_days=7` totals to single-day `worst_day_loss` from the | `per_machine[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | | Fleet `per_day[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | -- `{user_id}` — Replace with your account ID from **Account → Profile** in the console, or `vastai show user` (do not leave the curly-brace placeholder in the URL). +- `{user_id}` — Use your account ID from **Account → Profile** (recommended). Use `vastai show user` only if your API key includes `user_read`; `billing_read`-only keys cannot call it. Do not leave a curly-brace placeholder in the URL. - Settlement is evaluated on UTC day boundaries. Rows typically update within a few hours after UTC midnight. ## Tips for competitive SLA offers From 959236f99a55639b3aa9274486ecacb2110e6446 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 15:55:03 -0700 Subject: [PATCH 138/250] docs(sla): address doc-review consensus (cycle 89) Match OpenAPI sla_backtest trailing slash and clarify SLA query vs response-only fields. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 +- host/sla-backtester.mdx | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index c7cf8867..f816d197 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -183,7 +183,7 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA fields in `--raw` responses** (not query keys, except `expected_reliability` which is both a filter and a response field). Sort with `--order dph_total`. Do **not** put `dph_total` in the query string. +**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. **Response-only** SLA pricing fields in `--raw` output include `dph_total` (sort via `--order dph_total`) and `search.slaPremiumPerHour`; they are not CLI filter fields. Do **not** put `dph_total` in the query string. | Field | Meaning | | --- | --- | diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 6d4e3de0..25f716a7 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -77,9 +77,11 @@ The backtester is available through the REST API only. You must own the machine ``` -GET /api/v0/host/sla_backtest +GET /api/v0/host/sla_backtest/ ``` +Clients that normalize URLs may also accept the form without a trailing slash; prefer the OpenAPI path above. + Requires Bearer authentication. This endpoint is rate-limited like other host API endpoints — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) for retry guidance. ### Query parameters @@ -109,7 +111,7 @@ Minimal baseline (default 90-day lookback — no custom dates required): ```bash curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.95&p=0.6667" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667" ``` Custom date range (optional — relative UTC window): @@ -121,7 +123,7 @@ Custom date range (optional — relative UTC window): start=$(date -u -d '90 days ago' +%s) end=$(date -u +%s) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.95&p=0.6667&start_date=$start&end_date=$end" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667&start_date=$start&end_date=$end" ``` Compare two confidence levels on the same history: @@ -129,18 +131,18 @@ Compare two confidence levels on the same history: ```bash # Normal confidence (~67%, default 0.6667) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.99&p=0.6667" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667" # Tight (~83%) — tighter spread, lower simulated SLA charges curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.99&p=0.83" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.83" ``` Stress-test with flat 90% uptime: ```bash curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=12345&r=0.99&p=0.6667&reliability=0.90" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667&reliability=0.90" ``` ## Reading the response @@ -332,7 +334,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do out="$BT_DIR/sla_bt_$id.json" http=$(curl -s -o "$out" -w "%{http_code}" \ -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest?machine_id=$id&r=$r&p=$p") + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$r&p=$p") if [ "$http" != "200" ] || ! jq -e '.success == true' "$out" >/dev/null 2>&1; then echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' "$out" 2>/dev/null)" sleep 2; continue From 9b6fb3c46c383954d1217d77036ea3604f5ab65a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 15:57:45 -0700 Subject: [PATCH 139/250] docs(sla): address doc-review consensus (cycle 90) Clarify console vs CLI filter carry-over, move self-test after LIST, and reword client-side API filtering. Co-authored-by: Cursor --- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-offers.mdx | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 716633a4..792a07b5 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -CLI and API search only **quote** SLA pricing—they do not turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT** (search filters do not carry over to rent). If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). +CLI and API search only **quote** SLA pricing—they do not turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 2a6d9814..127d5381 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -391,7 +391,7 @@ Console users: open **Instances** → select your instance → **price details** Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). -To find instances with an SLA, filter **client-side** from the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`). Prefer client-side filtering in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone to detect an SLA. +To find instances with an SLA, post-process the API response in your application (filter or paginate locally)—not in the Vast web console. Prefer filtering the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`) in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone to detect an SLA. **You set at search/rent** diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index d524f877..6602985a 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -37,7 +37,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account** (do not host from a renter-only account), then [host setup](https://cloud.vast.ai/host/setup/) and confirm the machine appears on **Host → Machines** (healthy, priced). Configure **Set Pricing → SLA** (reliability commitment, confidence, and related fields) if you want SLA from the first rental—but do **not** press **LIST** to go live until you complete steps 2–6; step 7 is your first publish and verify. -2. Test on a [separate client account](/host/hosting-overview#testing-your-own-machine) (billed like any rental). +2. Create and fund a separate **client** account for later self-test (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine) account setup)—do **not** rent your machine yet; listing comes in step 7. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. Before your first SLA rental, read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. @@ -45,6 +45,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 7. **First publish and verify:** **Save** pricing, then click **LIST** (first publish only). If the machine is already listed, **Save** alone updates the live offer. - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). +8. **Self-test (after LIST):** With the separate client account from step 2, search by `machine_id`, rent with a **Reliability target**, and verify the SLA (billed like any rental)—see [Testing your own machine](/host/hosting-overview#testing-your-own-machine). ## Before you enable SLA From 5957ca2d431c4337fbc56819bd89f1640b90dac4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Mon, 5 Oct 2026 16:08:18 -0700 Subject: [PATCH 140/250] docs(sla): address doc-review consensus (cycle 92) Use portable jq for fleet backtest r validation and clarify Save vs LIST checklist order. Co-authored-by: Cursor --- host/sla-backtester.mdx | 4 ++-- host/sla-offers.mdx | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 25f716a7..f0b34bd0 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -318,8 +318,8 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -z "$r" ]; then r=$(echo "$machine" | jq -r '.sla_r_claim // empty') fi - if ! jq -n --arg r "$r" '($r | tonumber?) > 0' >/dev/null 2>&1; then - echo "skip $id: set Claim in console (**Set Pricing → SLA**) or export R=0.99"; continue + if ! jq -e -n --arg r "$r" 'try (($r | tonumber) > 0) catch false' >/dev/null 2>&1; then + echo "skip $id: set Claim (reliability commitment, sla_r_claim) in console (**Set Pricing → SLA**) or export R=0.99"; continue fi if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then echo "skip $id: set Confidence in console or PUT sla_sigma_x before backtest"; continue diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 6602985a..e59ddc0c 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -36,16 +36,17 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist -1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account** (do not host from a renter-only account), then [host setup](https://cloud.vast.ai/host/setup/) and confirm the machine appears on **Host → Machines** (healthy, priced). Configure **Set Pricing → SLA** (reliability commitment, confidence, and related fields) if you want SLA from the first rental—but do **not** press **LIST** to go live until you complete steps 2–6; step 7 is your first publish and verify. -2. Create and fund a separate **client** account for later self-test (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine) account setup)—do **not** rent your machine yet; listing comes in step 7. +1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**—listing not required yet). +2. Create and fund a separate **client** account for later self-test (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine) account setup)—do **not** rent your machine yet; listing comes in step 8. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. -4. Confirm SLA account access (**Set Pricing → SLA** panel visible; if missing, contact support). -5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)), then set the reliability commitment/confidence. Before your first SLA rental, read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. -6. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). -7. **First publish and verify:** **Save** pricing, then click **LIST** (first publish only). If the machine is already listed, **Save** alone updates the live offer. +4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. +5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. +6. Set and **Save** your reliability commitment and confidence in **Set Pricing → SLA**. +7. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). +8. **First publish and verify:** **Save** pricing, then click **LIST** (first publish only). If the machine is already listed, **Save** alone updates the live offer. - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). -8. **Self-test (after LIST):** With the separate client account from step 2, search by `machine_id`, rent with a **Reliability target**, and verify the SLA (billed like any rental)—see [Testing your own machine](/host/hosting-overview#testing-your-own-machine). +9. **Self-test (after LIST):** With the separate client account from step 2, search by `machine_id`, rent with a **Reliability target**, and verify the SLA (billed like any rental)—see [Testing your own machine](/host/hosting-overview#testing-your-own-machine). ## Before you enable SLA @@ -56,7 +57,7 @@ If you expect downtime during active rentals, notify renters before you take the **Pre-flight checklist (before tuning reliability commitment and confidence):** - Hosting requires a separate host account and hosting agreement — see [Account setup](/host/hosting-overview#account-setup-and-hosting-agreement) if you have not completed host onboarding. -- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai) to request access before configuring a fleet. Approval timing varies; complete host setup and a base listing first. +- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai) to request access before configuring a fleet. Approval timing varies; complete host setup and have base pricing ready in **Set Pricing** (a public **LIST** is not required for SLA approval—follow the [SLA host checklist](#sla-host-checklist) and **LIST** in step 8 when SLA economics are finalized). - Ensure your host daemon is current per the [host setup guide](https://cloud.vast.ai/host/setup/). - If listing fails with `sla_not_approved` or `sla_daemon_outdated`, resolve eligibility before changing SLA parameters. - **Planned maintenance tooling:** Use [`vastai schedule maint`](/host/cli/schedule-maint) or REST — see [Scheduled maintenance](#scheduled-maintenance). @@ -324,7 +325,7 @@ Omitted non-SLA fields retain their current listing values; only fields present vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, sla_r_claim, sla_sigma_x, price_gpu, end_date}' ``` -REST equivalent: `GET /api/v0/machines?user_id={user_id}` (`user_id` is required). Get `user_id` from **Account → Profile** or `vastai show user`. The CLI supplies `user_id` for you. +REST equivalent: `GET /api/v0/machines/?user_id={user_id}` (`user_id` is required). Get `user_id` from **Account → Profile** or `vastai show user`. The CLI supplies `user_id` for you. Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. From 3d6f75fb6864047eaa6069d2a35b9f924dda16c2 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 14:25:08 -0700 Subject: [PATCH 141/250] docs(sla): address doc-review consensus (cycle 93) Fix the fleet re-list expired-offer guard (jq without -e never skipped expired machines) and correct contracts verified against vast-cli and the dnotify handler: maintenance sdate is epoch seconds on REST too, schedule maint prompts for confirmation, CLI earnings dates parse in local time, and the CLI default query includes rented=false. Also clarify graduated settlement near the target, the exact UTC day index, maintenance request spacing vs the 2.5 s limit, charges until destroy, Destroy data loss, and check-before-retry on unclear outcomes. Co-Authored-By: Claude Opus 5.5 (1M context) --- api-reference/openapi.yaml | 19 +++++++++--------- .../openapi/yaml/schedule_maint.yaml | 10 ++++------ api-reference/openapi/yaml/sla_backtest.yaml | 1 + cli/reference/search-offers.mdx | 4 ++-- cli/reference/show-earnings.mdx | 4 ++-- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 13 ++++++------ host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 20 +++++++++---------- sdk/python/reference/create-instance.mdx | 6 +++++- snippets/host/cli/schedule-maint.mdx | 6 ++++-- 11 files changed, 46 insertions(+), 41 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 4a87f8fe..339635ba 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6401,18 +6401,15 @@ paths: - duration properties: sdate: - type: string - format: date-time - description: 'Start date and time of the maintenance window as an - ISO 8601 UTC datetime - - (for example `2026-08-01T02:00:00Z`). The CLI `--sdate` flag accepts - Unix epoch seconds + type: number + description: 'Start time of the maintenance window as Unix epoch + seconds (UTC), for example - and converts them to this format before calling the API. + `1785549600` (2026-08-01 02:00 UTC). The CLI `--sdate` flag sends + the same value. ' - example: '2026-08-01T02:00:00Z' + example: 1785549600 duration: type: integer description: Duration of the maintenance window in hours. @@ -9371,7 +9368,9 @@ paths: skipped_days: type: integer reliability: - type: number + type: + - number + - 'null' format: float fleet_reliability: type: number diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index 447ab2c6..5cf47099 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -35,13 +35,11 @@ paths: - duration properties: sdate: - type: string - format: date-time + type: number description: | - Start date and time of the maintenance window as an ISO 8601 UTC datetime - (for example `2026-08-01T02:00:00Z`). The CLI `--sdate` flag accepts Unix epoch seconds - and converts them to this format before calling the API. - example: '2026-08-01T02:00:00Z' + Start time of the maintenance window as Unix epoch seconds (UTC), for example + `1785549600` (2026-08-01 02:00 UTC). The CLI `--sdate` flag sends the same value. + example: 1785549600 duration: type: integer description: Duration of the maintenance window in hours. diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index 024eb4df..e8944dd0 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -104,6 +104,7 @@ paths: reliability: type: number format: float + nullable: true fleet_reliability: type: number format: float diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index f816d197..a37ca915 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -80,7 +80,7 @@ Filter examples (including SLA quotes) are under [Examples](#examples). Query sy ```bash # Marketplace reliability score (not SLA commitment) -# rented=false is optional (excludes slots you already rent); not part of the CLI default query +# rented=false (excludes slots you already rent) is already in the CLI default query; shown here explicitly vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=false' # SLA search quote (enable the SLA at rent via console/REST — see SLA) @@ -194,7 +194,7 @@ bool = True | False SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. -The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": {"eq": 0.95}`. In that example `allocated_storage` is a number, not an operator object. If the CLI warns that an SLA search field is unrecognized, upgrade the CLI and check that the results still match the filters you set. +The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": {"eq": 0.95}`. In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla`, `target_reliability`, and `expected_reliability`. The warning is harmless: the fields are still sent. To self-check, run `--raw | jq 'all(.offers[]; .expected_reliability > 0)'`. ## Global Options diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index 1929f5c6..59f720e3 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -37,7 +37,7 @@ vastai show earnings [OPTIONS] Machine id (optional) (alias: `--machine_id`) -`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). CLI `--start_date` / `--end_date` are calendar convenience; for REST-only query params `last_days`, `sday`, and `eday` (for example `last_days=1` polling or exact UTC day index), see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing) or [Show Earnings](/api-reference/billing/show-earnings). +`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). CLI `--start_date` / `--end_date` are calendar convenience: the CLI parses bare dates such as `2026-07-24` in your machine's local time, so append `T00:00:00Z` for an exact UTC day; for REST-only query params `last_days`, `sday`, and `eday` (for example `last_days=1` polling or exact UTC day index), see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing) or [Show Earnings](/api-reference/billing/show-earnings). ## Examples @@ -45,7 +45,7 @@ vastai show earnings [OPTIONS] vastai show earnings vastai show earnings --raw | jq '.per_machine[] | {machine_id, sla_earn}' # One machine (prefer --machine_id for SLA settlement checks) -vastai show earnings --machine_id 12345 --start_date $(date -u -d 'yesterday' +%F) --end_date $(date -u -d 'yesterday' +%F) --raw \ +vastai show earnings --machine_id 12345 --start_date "$(date -u -d 'yesterday' +%F)T00:00:00Z" --end_date "$(date -u -d 'yesterday' +%F)T00:00:00Z" --raw \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 792a07b5..62c38c06 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -115,4 +115,4 @@ Startup time depends on the template and is usually under 5 minutes. If waiting - Note: You're not charged while instances are loading - With slow internet and large images, downloads can take an hour or more -If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy** to stop ongoing compute charges (stopping alone may not end all billing—see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage) when you used an SLA). +If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy** to stop ongoing compute charges (stopping alone may not end all billing—see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage) when you used an SLA). Destroy permanently deletes the instance and its disk, so copy off anything you need first. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 127d5381..3727a1f7 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -16,7 +16,7 @@ An SLA is an optional reliability promise on an **on-demand** GPU rental. You do 2. **You** choose a **reliability target**: how much uptime you want. A higher target costs more. 3. You pay an **SLA fee** (a service level fee) on top of the GPU price. 4. Each day, Vast checks how long your instance was actually up. -5. If uptime met your reliability target, the host keeps the SLA fee. +5. If uptime met your reliability target, the host keeps the SLA fee. "Met" is judged on Vast's blended reliability measure (recent and longer-term uptime), not on a single day's raw uptime. Settlement is graduated: a day that looks close to the target can still produce a partial credit. 6. If uptime missed your reliability target, you receive a **service credit**. That credit can be larger than the SLA fee you paid that day. A few things people mix up: @@ -37,7 +37,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Before **RENT**, add an SSH key under **Account → Keys** (or choose a Jupyter/notebook template that does not require SSH)—see [Keys](/guides/reference/keys). Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. 3. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). 4. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing**. -5. When you are finished, **Destroy** the instance (not only **Stop**) to end ongoing charges—see [If your instance goes down](#if-your-instance-goes-down). +5. When you are finished, **Destroy** the instance (not only **Stop**) to end ongoing charges—see [If your instance goes down](#if-your-instance-goes-down). Destroy permanently deletes the instance and its disk, so copy off anything you need first. **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -229,7 +229,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -CLI search defaults are `external=false rentable=true verified=true` (see [search offers](/cli/reference/search-offers)). The body above matches those three filters. REST `POST /api/v0/bundles/` may default omitted `rented` to `{"eq": false}` per [Search Offers OpenAPI](/api-reference/search/search-offers)—that is **not** the same as the CLI default query (which does not send `rented`). Pass `rented` explicitly when you need a specific filter; do not assume omitted `rented` on REST matches CLI. +The CLI default query sends `external=false rentable=true verified=true rented=false` (the `--help` text omits `rented`; see [search offers](/cli/reference/search-offers)). The body above matches the first three filters, and REST `POST /api/v0/bundles/` may default omitted `rented` to `{"eq": false}` per [Search Offers OpenAPI](/api-reference/search/search-offers). Pass `rented` explicitly when you need different behavior. **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: @@ -274,7 +274,7 @@ curl -G "https://console.vast.ai/api/v1/instances/" \ --data-urlencode "limit=25" ``` -Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row. For the SLA fee: if the instance is not yet **running**, use `search.slaPremiumPerHour` (search-context pricing); once **running**, also check `instance.slaPremiumPerHour`. A missing `instance.slaPremiumPerHour` before startup is not a failed SLA rent. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, page with `after_token`. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). +Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row. For the SLA fee: if the instance is not yet **running**, use `search.slaPremiumPerHour` (search-context pricing); once **running**, also check `instance.slaPremiumPerHour`. A missing `instance.slaPremiumPerHour` before startup is not a failed SLA rent. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, confirm you used `new_contract` (not the offer id), then retry after a short delay, no more than about once per second (`show_instances` `x-rate-limit` threshold `1.0`). Use `after_token` paging only when listing without an `id` filter. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). The server default `limit` can be as low as **5** (maximum **25**). - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. @@ -290,6 +290,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Offer not found or not available | HTTP 404 `invalid_args` (`msg` may include `no_such_ask`) | Do not retry that id; search again and rent a current offer | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | +| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | Before sending the same `PUT` again, check `GET /api/v1/instances/` for a new contract. There is no idempotency key, so a blind retry can create a second paid rental. | | Too many requests | HTTP 429 | Wait and back off. Before retrying the same `PUT`, confirm with `GET /api/v1/instances/` whether the contract already exists. If retry returns `invalid_price`, `no_such_ask`, 404, or 410, re-search with the same `target_reliability` and storage, then rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 403 | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | @@ -363,8 +364,8 @@ Production settlement uses the multi-window reliability blend described above, n ## If your instance goes down 1. Save work and check **Instances** for host/maintenance status. -2. Remember: compute and SLA charges continue until settlement; credits apply to the **previous UTC day**, not the current hour. -3. **Console:** Open **Instances**, select the instance, then **Destroy** to stop future charges. Stopping alone may not end billing for a broken instance—see [Stop vs destroy](#what-you-pay-during-an-outage). +2. Remember: compute, storage, and SLA charges continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. +3. **Console:** Open **Instances**, select the instance, then **Destroy** to stop future charges. Stopping alone may not end billing for a broken instance—see [Stop vs destroy](#what-you-pay-during-an-outage). Destroy permanently deletes the instance and its disk, so copy off anything you need first. 4. After settlement, check **Account → Billing** in the console for SLA line items (not `GET /api/v0/charges/`). 5. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index f0b34bd0..8b349ec4 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -198,7 +198,7 @@ A successful response looks like this (fields abbreviated; counts are illustrati | Field | Meaning | | --- | --- | | `has_data` | `true` if at least one day in the range had earnings to replay. When `false`, there was no billable rental activity in the range: `covered_days` is `0`, `skipped_days` equals the number of days in the requested window, `daily_results` contains one zero-filled row per day in the window (not an empty array), summary totals are `0.0`, and top-level `reliability` is `null`. Try a wider window or a machine with more rental history. | -| `start_day`, `end_day` | UTC day indices. The API computes `day = floor(epoch_seconds / 86400)`. Same encoding as `daily_results[].day`. To convert a day index to an approximate UTC date: `date -u -d "@$((day * 86400))" +%Y-%m-%d` (Linux). Do not assume `day × 86400` equals UTC midnight for that calendar day. Most hosts can ignore these and use `start_date`/`end_date` in requests. | +| `start_day`, `end_day` | UTC day indices. The API computes `day = floor(epoch_seconds / 86400)`. Same encoding as `daily_results[].day`. `day × 86400` is exactly 00:00 UTC on that date. Convert with `date -u -d "@$((day * 86400))" +%F` (Linux) or `date -u -r $((day * 86400)) +%F` (macOS). Show Earnings `sday` / `eday` use the same day index. Most hosts can ignore these and use `start_date`/`end_date` in requests. | | `covered_days` | Days with rental activity replayed through SLA math | | `skipped_days` | Days in the range with no activity (zero-filled in `daily_results`) | | `reliability` | Actual uptime ratio over the range (`total uptime / total active time`) | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e59ddc0c..efe211a4 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -86,7 +86,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. If uptime met their reliability target, you keep the SLA fee. +6. If uptime met their reliability target, you keep the SLA fee. "Met" is judged on Vast's blended reliability measure (recent and longer-term uptime), not on a single day's raw uptime. Settlement is graduated: a day that looks close to the target can still produce a partial credit. 7. If uptime missed their reliability target, the renter receives a **service credit** from your earnings. One bad day can cost more than many days of fees. What this is not: @@ -394,7 +394,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: missing price_gpu/end_date/min_chunk"; continue fi now=$(date -u +%s) - if ! jq -n --argjson end "$end" --argjson now "$now" '$end > $now' >/dev/null 2>&1; then + if ! jq -e -n --argjson end "$end" --argjson now "$now" '$end > $now' >/dev/null 2>&1; then echo "skip machine_id=$id: end_date expired"; continue fi # Opt-in only: skip machines with no positive reliability commitment (do not invent 0.99) @@ -543,7 +543,7 @@ These scenarios show settlement when reliability **drops to or below** a 95% cli | Measured reliability (simplified) | You net (per day) | | --- | --- | -| At target (~95%) | −$42 (credit you owe) | +| Just below target on the blended measure (daily uptime may look close to 95%) | −$42 (credit you owe) | | Well below target (~90% or less) | −$84 (large credit owed) | To put the asymmetry in perspective: at ~$0.20/day in SLA charges, it takes roughly 210 strong days to accumulate the $42 you could lose on a single day at the target boundary. The SLA charge is a small fraction of daily compute, while credits scale against total daily compute. @@ -584,7 +584,7 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **Planned SLA maintenance (renters may qualify for a service credit — not guaranteed):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for service-credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. Renters should check **Instances** for status. Credited maintenance is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. Credit eligibility is evaluated on a case-by-case basis. -**CLI `--sdate` uses Unix epoch seconds (UTC)**; the REST body uses ISO 8601 UTC. **CLI `--duration` is in hours.** Schedule maintenance **sequentially** across a fleet. On HTTP 429, wait and retry with backoff (for example, `sleep 2` between machines). See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). +**`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash # Planned window ≥24 hours ahead (Linux GNU date). Example: day after tomorrow 02:00 UTC. @@ -595,7 +595,7 @@ vastai schedule maint MACHINE_ID \ --maintenance_category software ``` -REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate"` as ISO 8601 UTC at least 24 hours ahead (optional `"maintenance_reason": "OS kernel upgrade"`) — see [Schedule Maintenance](/api-reference/machines/schedule-maint). +REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate"` as Unix epoch seconds (UTC) at least 24 hours ahead (optional `"maintenance_reason": "OS kernel upgrade"`) — see [Schedule Maintenance](/api-reference/machines/schedule-maint). **Cancel or reschedule:** To cancel a window, use [`vastai cancel maint`](/host/cli/cancel-maint) (requires `machine_write`) or the [REST cancel-maintenance API](/api-reference/machines/cancel-maint). To reschedule, cancel the existing window, then run `schedule maint` with a new `--sdate` (still ≥24 hours ahead for planned SLA maintenance). @@ -644,22 +644,22 @@ SLA daily settlement (SLA charge kept / credit owed) does not currently emit hos **Linux (GNU date):** ```bash -vastai show earnings --machine_id --start_date $(date -u -d '7 days ago' +%F) --end_date $(date -u +%F) +vastai show earnings --machine_id --start_date "$(date -u -d '7 days ago' +%F)T00:00:00Z" --end_date "$(date -u +%F)T00:00:00Z" ``` **macOS:** ```bash -vastai show earnings --machine_id --start_date $(date -u -v-7d +%F) --end_date $(date -u +%F) +vastai show earnings --machine_id --start_date "$(date -u -v-7d +%F)T00:00:00Z" --end_date "$(date -u +%F)T00:00:00Z" ``` -On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. +Keep the `T00:00:00Z` suffix: the CLI parses bare dates such as `2026-07-24` in your machine's local time, so append `T00:00:00Z` for an exact UTC day. On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. **Linux (GNU date) — one UTC day (compare to `worst_day_loss`):** ```bash # Replace 12345 with your machine ID. -vastai show earnings --machine_id 12345 --start_date $(date -u -d 'yesterday' +%F) --end_date $(date -u -d 'yesterday' +%F) --raw \ +vastai show earnings --machine_id 12345 --start_date "$(date -u -d 'yesterday' +%F)T00:00:00Z" --end_date "$(date -u -d 'yesterday' +%F)T00:00:00Z" --raw \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` @@ -689,7 +689,7 @@ This endpoint is rate-limited. Poll `GET /api/v0/users/{user_id}/machine-earning When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs backtester `worst_day_loss`), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` for that calendar day. Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +- **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs backtester `worst_day_loss`), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. - **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 512c1b0a..888741aa 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -197,8 +197,12 @@ response = requests.put( }, timeout=60, ) -response.raise_for_status() +if not response.ok: + print(response.status_code, response.text) # body contains error / msg + response.raise_for_status() print(response.json()) # new_contract is the rental instance ID +# On a timeout, dropped connection, 429, or 5xx the rental may already exist: +# check GET /api/v1/instances/ before sending the same PUT again. ``` The same call with curl: diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index b31a2265..7d6d9d5e 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -10,6 +10,8 @@ vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_c `schedule maintenance` is an alias for `schedule maint` if your CLI build supports both spellings. Prefer `maint`. Requires `machine_write` on scoped API keys — see [Permissions](/api-reference/permissions). +The CLI prints the window and asks `Continue? [y/n]` before it sends the request. In scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call the [REST endpoint](/api-reference/machines/schedule-maint) directly. + ## Arguments @@ -19,7 +21,7 @@ vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_c ## Options - Maintenance start time as Unix epoch seconds (UTC). Example: `1677562671`. The API receives an ISO 8601 UTC datetime after conversion. + Maintenance start time as Unix epoch seconds (UTC). Example: `1677562671`. The CLI sends this value to the API unchanged (REST `sdate` is also epoch seconds). @@ -62,7 +64,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned SLA credit review). Across many machines, schedule sequentially and back off on HTTP 429. +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned SLA credit review). Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. ## Examples From 279d7a702535b249517088d9f81c19636ced02b9 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 14:34:40 -0700 Subject: [PATCH 142/250] docs(sla): address doc-review consensus (cycle 94) Correct contracts verified against code: CLI search --raw prints a bare array (jq .offers[] broke), and sla_not_approved / sla_daemon_outdated return 403, not 400. Use the console's actual "SLA Fee" label, split the console quick start so the SSH key comes first, and give hosts an ordered severe-outage runbook that warns create_asks re-publishes. Co-Authored-By: Claude Opus 5.5 (1M context) --- api-reference/openapi.yaml | 7 ++++--- api-reference/openapi/yaml/list_machine.yaml | 6 +++--- cli/reference/search-offers.mdx | 2 +- cli/reference/show-earnings.mdx | 5 +++-- guides/instances/choosing/find-and-rent.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 20 +++++++++++--------- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 17 +++++++++++------ 8 files changed, 36 insertions(+), 27 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 339635ba..c1d2e533 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4691,8 +4691,6 @@ paths: enum: - invalid_args - invalid_sla_params - - sla_not_approved - - sla_daemon_outdated example: invalid_sla_params msg: type: string @@ -4713,7 +4711,8 @@ paths: type: string example: Your key lacks the machine_write permission group '403': - description: "Forbidden \u2014 machine locked" + description: "Forbidden \u2014 machine locked, host not approved for SLA,\ + \ or daemon too old for SLA" content: application/json: schema: @@ -4723,6 +4722,8 @@ paths: type: string enum: - machine_locked + - sla_not_approved + - sla_daemon_outdated example: machine_locked msg: type: string diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 03047865..59ebe5c2 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -156,8 +156,6 @@ paths: enum: - invalid_args - invalid_sla_params - - sla_not_approved - - sla_daemon_outdated example: invalid_sla_params msg: type: string @@ -178,7 +176,7 @@ paths: type: string example: Your key lacks the machine_write permission group '403': - description: Forbidden — machine locked + description: Forbidden — machine locked, host not approved for SLA, or daemon too old for SLA content: application/json: schema: @@ -188,6 +186,8 @@ paths: type: string enum: - machine_locked + - sla_not_approved + - sla_daemon_outdated example: machine_locked msg: type: string diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index a37ca915..bd1c636c 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -194,7 +194,7 @@ bool = True | False SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. -The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": {"eq": 0.95}`. In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla`, `target_reliability`, and `expected_reliability`. The warning is harmless: the fields are still sent. To self-check, run `--raw | jq 'all(.offers[]; .expected_reliability > 0)'`. +The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": {"eq": 0.95}`. In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla`, `target_reliability`, and `expected_reliability`. The warning is harmless: the fields are still sent. To self-check, run `--raw | jq 'all(.[]; .expected_reliability > 0)'` (CLI `--raw` prints a bare array of offers, not an `offers` object). ## Global Options diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index 59f720e3..a13cfbc1 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -37,14 +37,15 @@ vastai show earnings [OPTIONS] Machine id (optional) (alias: `--machine_id`) -`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). CLI `--start_date` / `--end_date` are calendar convenience: the CLI parses bare dates such as `2026-07-24` in your machine's local time, so append `T00:00:00Z` for an exact UTC day; for REST-only query params `last_days`, `sday`, and `eday` (for example `last_days=1` polling or exact UTC day index), see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing) or [Show Earnings](/api-reference/billing/show-earnings). +`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). `--start_date` and `--end_date` are convenience options. The CLI parses bare dates such as `2026-07-24` in your machine's local time, so append `T00:00:00Z` for an exact UTC day. For REST-only query params `last_days`, `sday`, and `eday` (for example `last_days=1` polling or exact UTC day index), see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing) or [Show Earnings](/api-reference/billing/show-earnings). ## Examples ```bash vastai show earnings vastai show earnings --raw | jq '.per_machine[] | {machine_id, sla_earn}' -# One machine (prefer --machine_id for SLA settlement checks) +# One machine, one UTC day (prefer --machine_id for SLA settlement checks). Linux (GNU date); +# on macOS (BSD date) use $(date -u -v-1d +%F) for yesterday. vastai show earnings --machine_id 12345 --start_date "$(date -u -d 'yesterday' +%F)T00:00:00Z" --end_date "$(date -u -d 'yesterday' +%F)T00:00:00Z" --raw \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 62c38c06..62428f88 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -54,11 +54,11 @@ All stats shown are the portion of the total machine rented. - Disk speed: The speed of the local storage on the machine in MB/s - Total available disk: The maximum amount of disk space available - DLPERF score: A custom deep learning performance score -- Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. On SLA listings, the breakdown also shows an **SLA charge** line — see [SLA](/guides/instances/choosing/sla-coverage). +- Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. On SLA listings, the breakdown also shows an **SLA Fee** line — see [SLA](/guides/instances/choosing/sla-coverage). - Max Duration: The maximum length of a rental contract on this machine - Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host reliability commitment. - Rental Option: RENT button -- **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA fee** line in the price breakdown (the console may label it **SLA charge**). An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). +- **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA Fee** line in the price breakdown. An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). CLI and API search only **quote** SLA pricing—they do not turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 3727a1f7..a46f23a6 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -25,19 +25,21 @@ A few things people mix up: - The GPU bill does **not** stop during an outage. SLA pays you back later as a credit, usually after the next UTC midnight. - A search filter does **not** turn on an SLA. You have to set a reliability target when you rent, in the web console or with the API. The CLI cannot turn SLA on today. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. -- If the price breakdown has **no SLA fee line**, you do not have an SLA. The console may also label that line **SLA charge**. In API responses the same amount is `slaPremiumPerHour`. +- If the price breakdown has **no SLA Fee line**, you do not have an SLA. In **Account → Billing** the same charge appears as **SLA Fee**, and credits as **Service Credit**. In API responses the hourly amount is `slaPremiumPerHour`. Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). **Console quick start (no API key):** -Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) has credit or a payment method, and pick a [template](/guides/instances/choosing/templates) in Search (see [Finding & Renting](/guides/instances/choosing/find-and-rent)). +Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) has credit or a payment method, add an SSH key under **Account → Keys** (or plan to use a Jupyter/notebook template that does not require SSH; see [Keys](/guides/reference/keys)), and pick a [template](/guides/instances/choosing/templates) in Search (see [Finding & Renting](/guides/instances/choosing/find-and-rent)). 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. -2. In **Search filters** (left bar), set **Reliability target**, confirm an **SLA fee** line in the price breakdown, set instance disk on the slider, then **RENT**. Before **RENT**, add an SSH key under **Account → Keys** (or choose a Jupyter/notebook template that does not require SSH)—see [Keys](/guides/reference/keys). Console default disk is 10 GB; if you quoted via CLI/REST, match that disk number or rent can fail with `invalid_price`. -3. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA charge** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). -4. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing**. -5. When you are finished, **Destroy** the instance (not only **Stop**) to end ongoing charges—see [If your instance goes down](#if-your-instance-goes-down). Destroy permanently deletes the instance and its disk, so copy off anything you need first. +2. In **Search filters** (left bar), set **Reliability target**. +3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. +4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown, then click **RENT**. +5. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA Fee** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). +6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing**. +7. When you are finished, **Destroy** the instance (not only **Stop**) to end ongoing charges—see [If your instance goes down](#if-your-instance-goes-down). Destroy permanently deletes the instance and its disk, so copy off anything you need first. **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -120,8 +122,8 @@ Search **quotes** SLA pricing. The SLA starts only when you set **Reliability ta 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). 2. In Search filters (left filter bar), set **Reliability target** to your desired reliability target — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. 3. Optionally narrow results with an SLA-enabled / `has_sla` filter if shown. Filtering listings is **not** the same as enabling the SLA. -4. Before you click **RENT**, confirm the price breakdown shows an **SLA fee** line. No SLA fee line means that rental has no SLA. -5. **Disk before RENT:** Set instance disk on the console slider before **RENT**. If you quoted via CLI or REST, match `allocated_storage` / `disk` to that quote (REST `disk` ≥ 8 when set)—mismatched defaults cause `invalid_price`. See the storage table in [API automation](#api-automation). +4. Before you click **RENT**, confirm the price breakdown shows an **SLA Fee** line. No SLA Fee line means that rental has no SLA. +5. **Disk before RENT:** Set instance disk on the console slider before **RENT**. If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 6. Rent as usual. Your target is locked at rent time. @@ -374,7 +376,7 @@ Production settlement uses the multi-window reliability blend described above, n ### In the web console (active instances) 1. Open **Instances** and select your running instance. -2. Open **price details** (or the instance billing panel) and confirm an **SLA charge** line is present. +2. Open **price details** (or the instance billing panel) and confirm an **SLA Fee** line is present. 3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. If you do not see a target or SLA charge, you likely rented without the SLA. ### API integrators diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index c3597390..9574f365 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -235,7 +235,7 @@ Use `./vastai` instead of `vastai` when running from the install directory. CLI self-tests create **non-SLA** rentals (`vastai create instance` does not accept `target_reliability`). To test SLA contract terms on your own offer: 1. Create a separate client account (see above), or use REST from that account. -2. In the console Search filters, set a **Reliability target**, rent your own offer, and confirm an **SLA charge** line before continuing — or `PUT /api/v0/asks/{id}/` with `target_reliability`. +2. In the console Search filters, set a **Reliability target**, rent your own offer, and confirm an **SLA Fee** line before continuing — or `PUT /api/v0/asks/{id}/` with `target_reliability`. 3. Destroy the test instance when done. See [SLA](/guides/instances/choosing/sla-coverage) for renter-side details. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index efe211a4..a1697824 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -338,7 +338,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge **Console hosts:** skip this section. Enable an SLA with [Web console](#web-console) and check settlement in [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). -This loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that already have `sla_r_claim > 0`. +Use this loop to republish SLA terms across a fleet, for example after a daemon update. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that already have `sla_r_claim > 0`. `create_asks` defaults `sla_sigma_x` to `0.5` when you omit it on a write. This guide does **not** treat a missing `sla_sigma_x` in `show machines --raw` as that default—the raw payload may omit the field even when you intend Normal confidence. The loop **skips and logs** those IDs so it never silently writes `0.5`. Set **Confidence** in the console (or PUT `sla_sigma_x` for that machine), then re-run. A skip is not “SLA-ready.” @@ -438,7 +438,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{"machine": 12345, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` -**Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). +**Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. #### Common errors @@ -446,10 +446,10 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | --- | --- | --- | | 401 | `success: false` + `msg` (+ optional `error`) | Missing `machine_write` or other required permission | | 403 | `machine_locked` | Machine is decommissioned or migration-locked | +| 403 | `sla_not_approved` | Host account is not approved to create SLA asks | +| 403 | `sla_daemon_outdated` | Machine daemon build is too old for SLA listing | | 400 | `invalid_args` | Machine ID not found for your account, or malformed / incompatible request body | | 400 | `invalid_sla_params` | SLA parameters failed validation | -| 400 | `sla_not_approved` | Host account is not approved to create SLA asks | -| 400 | `sla_daemon_outdated` | Machine daemon build is too old for SLA listing | **`machine_locked`:** Returned when a machine is decommissioned or migration-locked. If you are migrating hardware, finish or cancel active rentals first, remove or update the listing as needed, and contact support if the machine remains locked. Existing SLA terms on active contracts remain in force until those contracts end. @@ -509,7 +509,7 @@ Verify after listing — filter the offer you care about; sliced machines often ```bash vastai search offers 'machine_id=12345 verified=any has_sla=true target_reliability=0.95' --storage 10 --raw \ - | jq '[.offers[] | select(.is_bid == false) | {id, num_gpus, dph_total, expected_reliability, reliability}]' + | jq '[.[] | select(.is_bid == false) | {id, num_gpus, dph_total, expected_reliability, reliability}]' ``` ### If reliability is strong relative to the client's target @@ -617,7 +617,12 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **`sla_not_approved`** — Contact support; you can keep a non-SLA listing while approval is pending. - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — Review reliability; re-run the backtester with a low `reliability` stress value (for example `0.01`). -- **Severe outage** — Disable SLA on new contracts: open **Host → Machines** → **Set Pricing → SLA**, set the reliability commitment to `0` (or use API `sla_r_claim=0`); contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. +- **Severe outage (active SLA contracts):** + 1. Notify renters now: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS`. + 2. Stop new SLA rentals. The fastest way is `vastai unlist machine MACHINE_ID`, which publishes nothing. Alternatively, set the reliability commitment to `0` in **Set Pricing → SLA** (or API `sla_r_claim=0`), but only on machines that are currently listed, because `create_asks` publishes a live listing. + 3. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. + 4. After the next UTC midnight, check `sla_earn` for the affected day. + 5. Contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. ## Monitoring SLA after listing From 4b4998cf6202a47e212a40c5e33774c407c1e141 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 16:14:07 -0700 Subject: [PATCH 143/250] docs(sla): rewrite SLA backtester to the current API contract (cycle 94) The backtester docs described a retired contract: ?r= and ?reliability= now return 400 (extra params are forbidden), and the response no longer has summary/worst_day_loss/daily_results. Document the backend master contract (r_claim, p, optional r_target; r_eff, r_be, and the per-day escrow flow ledger), add 403 sla_disabled and the 2.0 s rate limit, and replace worst_day_loss guidance with a jq-derived largest single-day credit. The backtester stays host-only. Co-Authored-By: Claude Opus 5.5 (1M context) --- api-reference/openapi.yaml | 232 +++++++------ api-reference/openapi/yaml/sla_backtest.yaml | 193 ++++++----- host/sla-backtester.mdx | 323 +++++++++---------- host/sla-offers.mdx | 38 +-- 4 files changed, 403 insertions(+), 383 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index c1d2e533..ab560992 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9269,18 +9269,24 @@ paths: get: summary: sla backtest operationId: slaBacktest - description: 'Replays a machine''s historical compute earnings and uptime through - SLA settlement math + description: 'Host only. Replays one machine''s historical compute earnings + and uptime through production - to preview SLA charges and credits before listing with SLA. The maximum date - range is + SLA settlement under what-if SLA terms, and returns a per-day ledger of the + money that moved - 366 days (inclusive); the default lookback is 90 days when custom dates are - omitted. + between the renter, the SLA escrow, and the host. The maximum date range is + 366 days + (inclusive); the default lookback is 90 days when custom dates are omitted. + Unknown query - Requires `machine_read` permission. See [SLA Earnings Backtester](/host/sla-backtester) - for usage guide.' + parameters are rejected with `400 bad_request`. + + + Requires `machine_read` permission and ownership of the machine. See + + [SLA Earnings Backtester](/host/sla-backtester) for the usage guide.' security: - BearerAuth: [] parameters: @@ -9289,8 +9295,9 @@ paths: required: true schema: type: integer + minimum: 1 description: ID of your machine. - - name: r + - name: r_claim in: query required: true schema: @@ -9298,9 +9305,9 @@ paths: format: float minimum: 0 exclusiveMinimum: true - maximum: 0.9999 - description: Reliability level to simulate (greater than 0 and at most 0.9999). - Used as both claim and client target in the simulation. Exactly 1.0 is rejected. + maximum: 0.99999 + description: Host reliability commitment to simulate (the `sla_r_claim` you + plan to list). - name: p in: query schema: @@ -9308,41 +9315,36 @@ paths: format: float minimum: 0 exclusiveMinimum: true - exclusiveMaximum: true maximum: 1 + exclusiveMaximum: true default: 0.6667 - description: Host confidence (greater than 0 and less than 1). Maps to sla_sigma_x - when listing. Default 0.6667 (normal). - - name: start_date - in: query - schema: - type: integer - description: Range start as Unix epoch seconds. Default is 90 days before - end_date. - - name: end_date - in: query - schema: - type: integer - description: Range end as Unix epoch seconds. Default is now. - - name: reliability + description: 'Host confidence. Uses a different scale from listing `sla_sigma_x` + + (`p = 1 / (1 + sla_sigma_x)`; Tight 0.83, Normal 0.6667, Wide 0.50). Default + 0.6667 (Normal). + + ' + - name: r_target in: query schema: type: number format: float minimum: 0 exclusiveMinimum: true - maximum: 1 - description: Optional flat uptime override (greater than 0 and at most 1) - for all replayed days. Exactly 0 is rejected. - - name: beta + maximum: 0.99999 + description: Renter reliability target to simulate. Must not exceed `r_claim`. + Defaults to `r_claim`. + - name: start_date in: query schema: type: number - format: float - description: "Timescale mix used in settlement simulation. Not user-configurable\ - \ for host API keys \u2014\nthe API derives weighting from `r` (recent vs\ - \ longer-term uptime). Omit this parameter.\nThe response `params.beta`\ - \ echoes the derived value.\n" + description: Range start as Unix epoch seconds. Default is 90 days before + end_date. + - name: end_date + in: query + schema: + type: number + description: Range end as Unix epoch seconds. Default is now. responses: '200': description: Successful response @@ -9357,99 +9359,107 @@ paths: type: integer has_data: type: boolean - description: false when no days in the range had earnings to replay. + description: false when no day in the range had rental earnings + to replay. start_day: type: integer - description: UTC day index (days since 1970-01-01). + description: UTC day index (floor(epoch_seconds / 86400)). end_day: type: integer - description: UTC day index (days since 1970-01-01). - covered_days: - type: integer - skipped_days: - type: integer - reliability: + description: UTC day index (floor(epoch_seconds / 86400)). + r_eff: type: - number - 'null' format: float - fleet_reliability: + description: 'Effective reliability: the constant reliability + that would have produced the + + service credits paid in the window. null when the window had + no deposits. + + ' + r_be: type: number format: float - description: Average reliability across your machines (including - this one). Context only. - params: - type: object - properties: - r: - type: number - format: float - p: - type: number - format: float - sigma_x: - type: number - format: float - reliability: - type: - - number - - 'null' - format: float - beta: - type: number - format: float - daily_results: + description: 'Break-even reliability: where SLA fees and service + credits cancel out. If r_eff + + is above r_be, SLA was net positive for the host over the window. + + ' + days: type: array + description: One row per UTC day from start_day to end_day. All + flows are non-negative dollar amounts moved that day. items: type: object properties: day: type: integer - gpu: - type: number - format: float - storage: + client_compute_to_escrow: type: number format: float - bandwidth: + description: Renter compute payment for the day held in + SLA escrow (host net of platform fee). + client_premium_to_escrow: type: number format: float - uptime: + description: SLA fee paid in for the day. + escrow_to_client_balance: type: number format: float - sla: + description: Service credits paid to the renter that day. + escrow_to_host_balance: type: number format: float - historical_sla: - type: number + description: Amount released from escrow to the host that + day. + reliability: + type: + - number + - 'null' format: float - summary: + description: Measured uptime fraction for the day (0-1); + null when the machine had no rental data that day. + params: type: object + description: SLA terms the replay used, after defaulting. properties: - total_gpu: - type: number - format: float - total_storage: - type: number - format: float - total_bandwidth: - type: number - format: float - total_sla: - type: number - format: float - total_earnings: + r_claim: type: number format: float - total_historical_sla: + r_target: type: number format: float - worst_day_loss: + p: type: number format: float - reserve: + beta: type: number format: float + description: Recent vs long-term uptime weighting, derived + automatically from r_target. Not a host setting. + example: + success: true + machine_id: 12345 + has_data: true + start_day: 20568 + end_day: 20657 + r_eff: 0.9987 + r_be: 0.9712 + days: + - day: 20568 + client_compute_to_escrow: 78.12 + client_premium_to_escrow: 0.19 + escrow_to_client_balance: 0.0 + escrow_to_host_balance: 76.4 + reliability: 1.0 + params: + r_claim: 0.99 + r_target: 0.99 + beta: 0.5 + p: 0.6667 '400': description: Bad Request content: @@ -9457,25 +9467,48 @@ paths: schema: type: object properties: + success: + type: boolean + example: false error: type: string enum: - - invalid_range - - range_too_large - bad_request - invalid_params + - invalid_range + - range_too_large + description: 'bad_request: missing, out-of-range, or unknown parameter. + + invalid_params: SLA terms don''t combine (for example r_target + > r_claim). + + invalid_range: start_date after end_date. range_too_large: more + than 366 days. + + ' msg: type: string + '401': + description: "Unauthorized \u2014 missing or invalid API key, or missing\ + \ machine_read permission" '403': - description: "Forbidden \u2014 not machine owner" + description: "Forbidden \u2014 not the machine owner, or SLA is not currently\ + \ enabled on the platform" content: application/json: schema: type: object properties: + success: + type: boolean + example: false error: type: string - example: not_owner + enum: + - not_owner + - sla_disabled + msg: + type: string '404': description: Machine not found content: @@ -9483,6 +9516,9 @@ paths: schema: type: object properties: + success: + type: boolean + example: false error: type: string example: machine_not_found diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index e8944dd0..d814f19d 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -1,7 +1,7 @@ openapi: 3.0.0 info: title: Vast.ai API - SLA Backtest - description: Replay historical machine earnings through SLA settlement math. + description: Replay historical machine earnings through SLA settlement (host only). version: 1.0.0 servers: - url: https://console.vast.ai @@ -12,11 +12,14 @@ paths: summary: sla backtest operationId: slaBacktest description: | - Replays a machine's historical compute earnings and uptime through SLA settlement math - to preview SLA charges and credits before listing with SLA. The maximum date range is - 366 days (inclusive); the default lookback is 90 days when custom dates are omitted. + Host only. Replays one machine's historical compute earnings and uptime through production + SLA settlement under what-if SLA terms, and returns a per-day ledger of the money that moved + between the renter, the SLA escrow, and the host. The maximum date range is 366 days + (inclusive); the default lookback is 90 days when custom dates are omitted. Unknown query + parameters are rejected with `400 bad_request`. - Requires `machine_read` permission. See [SLA Earnings Backtester](/host/sla-backtester) for usage guide. + Requires `machine_read` permission and ownership of the machine. See + [SLA Earnings Backtester](/host/sla-backtester) for the usage guide. security: - BearerAuth: [] parameters: @@ -25,8 +28,9 @@ paths: required: true schema: type: integer + minimum: 1 description: ID of your machine. - - name: r + - name: r_claim in: query required: true schema: @@ -34,8 +38,8 @@ paths: format: float minimum: 0 exclusiveMinimum: true - maximum: 0.9999 - description: Reliability level to simulate (greater than 0 and at most 0.9999). Used as both claim and client target in the simulation. Exactly 1.0 is rejected. + maximum: 0.99999 + description: Host reliability commitment to simulate (the `sla_r_claim` you plan to list). - name: p in: query schema: @@ -43,39 +47,31 @@ paths: format: float minimum: 0 exclusiveMinimum: true - exclusiveMaximum: true maximum: 1 + exclusiveMaximum: true default: 0.6667 - description: Host confidence (greater than 0 and less than 1). Maps to sla_sigma_x when listing. Default 0.6667 (normal). - - name: start_date - in: query - schema: - type: integer - description: Range start as Unix epoch seconds. Default is 90 days before end_date. - - name: end_date - in: query - schema: - type: integer - description: Range end as Unix epoch seconds. Default is now. - - name: reliability + description: | + Host confidence. Uses a different scale from listing `sla_sigma_x` + (`p = 1 / (1 + sla_sigma_x)`; Tight 0.83, Normal 0.6667, Wide 0.50). Default 0.6667 (Normal). + - name: r_target in: query schema: type: number format: float minimum: 0 exclusiveMinimum: true - maximum: 1 - description: Optional flat uptime override (greater than 0 and at most 1) for all replayed days. Exactly 0 is rejected. - - name: beta + maximum: 0.99999 + description: Renter reliability target to simulate. Must not exceed `r_claim`. Defaults to `r_claim`. + - name: start_date in: query schema: type: number - format: float - description: | - Timescale mix used in settlement simulation. Not user-configurable for host API keys — - the API derives weighting from `r` (recent vs longer-term uptime). Omit this parameter. - The response `params.beta` echoes the derived value. - + description: Range start as Unix epoch seconds. Default is 90 days before end_date. + - name: end_date + in: query + schema: + type: number + description: Range end as Unix epoch seconds. Default is now. responses: '200': description: Successful response @@ -90,96 +86,92 @@ paths: type: integer has_data: type: boolean - description: false when no days in the range had earnings to replay. + description: false when no day in the range had rental earnings to replay. start_day: type: integer - description: UTC day index (days since 1970-01-01). + description: UTC day index (floor(epoch_seconds / 86400)). end_day: type: integer - description: UTC day index (days since 1970-01-01). - covered_days: - type: integer - skipped_days: - type: integer - reliability: + description: UTC day index (floor(epoch_seconds / 86400)). + r_eff: type: number format: float nullable: true - fleet_reliability: + description: | + Effective reliability: the constant reliability that would have produced the + service credits paid in the window. null when the window had no deposits. + r_be: type: number format: float - description: Average reliability across your machines (including this one). Context only. - params: - type: object - properties: - r: - type: number - format: float - p: - type: number - format: float - sigma_x: - type: number - format: float - reliability: - type: number - format: float - nullable: true - beta: - type: number - format: float - daily_results: + description: | + Break-even reliability: where SLA fees and service credits cancel out. If r_eff + is above r_be, SLA was net positive for the host over the window. + days: type: array + description: One row per UTC day from start_day to end_day. All flows are non-negative dollar amounts moved that day. items: type: object properties: day: type: integer - gpu: - type: number - format: float - storage: + client_compute_to_escrow: type: number format: float - bandwidth: + description: Renter compute payment for the day held in SLA escrow (host net of platform fee). + client_premium_to_escrow: type: number format: float - uptime: + description: SLA fee paid in for the day. + escrow_to_client_balance: type: number format: float - sla: + description: Service credits paid to the renter that day. + escrow_to_host_balance: type: number format: float - historical_sla: + description: Amount released from escrow to the host that day. + reliability: type: number format: float - summary: + nullable: true + description: Measured uptime fraction for the day (0-1); null when the machine had no rental data that day. + params: type: object + description: SLA terms the replay used, after defaulting. properties: - total_gpu: - type: number - format: float - total_storage: - type: number - format: float - total_bandwidth: - type: number - format: float - total_sla: + r_claim: type: number format: float - total_earnings: + r_target: type: number format: float - total_historical_sla: - type: number - format: float - worst_day_loss: + p: type: number format: float - reserve: + beta: type: number format: float + description: Recent vs long-term uptime weighting, derived automatically from r_target. Not a host setting. + example: + success: true + machine_id: 12345 + has_data: true + start_day: 20568 + end_day: 20657 + r_eff: 0.9987 + r_be: 0.9712 + days: + - day: 20568 + client_compute_to_escrow: 78.12 + client_premium_to_escrow: 0.19 + escrow_to_client_balance: 0.0 + escrow_to_host_balance: 76.4 + reliability: 1.0 + params: + r_claim: 0.99 + r_target: 0.99 + beta: 0.5 + p: 0.6667 '400': description: Bad Request content: @@ -187,25 +179,41 @@ paths: schema: type: object properties: + success: + type: boolean + example: false error: type: string enum: - - invalid_range - - range_too_large - bad_request - invalid_params + - invalid_range + - range_too_large + description: | + bad_request: missing, out-of-range, or unknown parameter. + invalid_params: SLA terms don't combine (for example r_target > r_claim). + invalid_range: start_date after end_date. range_too_large: more than 366 days. msg: type: string + '401': + description: Unauthorized — missing or invalid API key, or missing machine_read permission '403': - description: Forbidden — not machine owner + description: Forbidden — not the machine owner, or SLA is not currently enabled on the platform content: application/json: schema: type: object properties: + success: + type: boolean + example: false error: type: string - example: not_owner + enum: + - not_owner + - sla_disabled + msg: + type: string '404': description: Machine not found content: @@ -213,6 +221,9 @@ paths: schema: type: object properties: + success: + type: boolean + example: false error: type: string example: machine_not_found @@ -226,3 +237,7 @@ components: type: http scheme: bearer description: Bearer authentication with API key in Authorization header +x-rate-limit: + threshold: 2.0 + per: request + description: Maximum request frequency per IP address for this endpoint diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 8b349ec4..c472b755 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -1,6 +1,6 @@ --- title: "SLA Earnings Backtester" -description: "Host-only. Replay your machine's historical earnings through SLA math to preview SLA charges and credits before listing." +description: "Host-only. Replay your machine's historical earnings through SLA settlement to preview SLA fees and service credits before listing." "canonical": "/host/sla-backtester" --- @@ -16,85 +16,79 @@ How much could SLA settlement cost given your reliability commitment and confide | Simulate historical earnings for one machine | This page's single-machine `curl` example | | Review many machines at once | [Fleet workflow](#fleet-workflow) below (advanced; Linux/macOS + `jq`) | -**Console hosts:** use **Set Pricing → SLA** in the web console to preview SLA charges — you do not need this API. +**Console hosts:** use **Set Pricing → SLA** in the web console to preview SLA fees — you do not need this API. -**API hosts:** this endpoint replays historical earnings through SLA math to estimate SLA charges and worst-day credit risk before listing. Query parameters `r` (reliability commitment and simulated target) and `p` (host confidence) are defined under [Query parameters](#query-parameters). - -It replays your machine's **real historical compute earnings and reliability** through the same SLA settlement math used in production, then compares the simulated result to what you actually earned from SLA (if anything). +**API hosts:** this endpoint replays your machine's **real historical compute earnings and uptime** through the same SLA settlement used in production, under the SLA terms you choose. Query parameters `r_claim` (reliability commitment), `p` (confidence), and the optional `r_target` (simulated renter target) are defined under [Query parameters](#query-parameters). -**Don't want to use the API?** The backtester is optional. Use the web console SLA preview and the [economics walkthrough](/host/sla-offers#economics-walkthrough) on SLA Offers to evaluate SLA before listing. The backtester is for hosts who want historical replay via the API. +**Don't want to use the API?** The backtester is optional. Use the web console SLA preview and the [economics walkthrough](/host/sla-offers#economics-walkthrough) on SLA Offers to evaluate SLA before listing. ## When to use it -Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. - -If `has_data` is `false`, widen the date range or pick a machine with more rental activity. +Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. If `has_data` is `false`, widen the date range or pick a machine with more rental activity. Use the backtester to: - Pick a reliability commitment and confidence before you enable SLA on a listing -- Compare how SLA charge and worst-case credit change across targets -- Stress-test a lower reliability assumption before you commit -- Compare to history — each day includes `historical_sla`, your machine's realized SLA earnings on that day (zero if you were not offering SLA) +- See how SLA fees and service credits change when renters choose a lower target than your commitment +- Find your **break-even reliability** (`r_be`): the reliability below which SLA would have cost you money For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). ## How it works -1. You choose a machine, date range, reliability level (`r`), and confidence (`p`). -2. The API loads per-day earnings from your machine's rental history. -3. For each active day, it computes GPU, storage, and bandwidth earnings plus simulated SLA host earnings. -4. It returns a day-by-day breakdown and summary totals. +1. You choose a machine, a date range, your reliability commitment (`r_claim`), your confidence (`p`), and optionally a simulated renter target (`r_target`). +2. The API loads your machine's per-day compute earnings and uptime for the range. +3. It replays those days as **one simulated SLA contract** through production SLA settlement. +4. It returns one row per UTC day showing the money that moved that day, plus two summary reliabilities (`r_eff`, `r_be`). + +**How SLA money moves.** On an SLA contract, the renter's daily compute payment and SLA fee go into an SLA escrow for that contract. Escrow pays service credits to the renter and releases the rest to you. Each row in `days` shows those four flows for one day. Over the full window, what went in equals what came out, so your **net SLA result** is the SLA fees paid in minus the service credits paid out. -**Simulated vs listing parameters.** In the backtester, the reliability **commitment and the client reliability target are both set to `r`**. That is a conservative what-if: it pretends every client targeted your reliability commitment. When you list, you set only **`sla_r_claim`** (and `sla_sigma_x`); clients choose their own `target_reliability` at search/rent time. Workflow: backtest `worst_day_loss` at a candidate reliability commitment, then verify visible SLA fees in **Set Pricing → SLA** (or `dph_total` in search at realistic client targets) before listing. +**Simulated vs live renters.** If you omit `r_target`, the simulation assumes the renter targeted your full reliability commitment (`r_target = r_claim`). That is a conservative what-if: it produces the highest SLA fees and the most credit exposure. Live renters choose their own targets, often below your commitment. Pass `r_target` (for example `0.95` with `r_claim=0.99`) to model those renters. -**Active vs idle days.** **Idle days** are days with no rental earnings on the machine (no active compute rental). These days typically produce no SLA charge or credit in the simulation. Days with no rental activity appear in the results as zero-filled rows but do not count toward `covered_days`. Only days with actual earnings are replayed through SLA math. +**Active vs idle days.** Days with no rental earnings appear as rows with all flows `0` and `reliability: null`. They are not outages: the simulated contract simply pauses. -**Simulation vs live listing** -- The backtester sets the reliability commitment equal to target and may show higher SLA charges than live listing when clients choose targets below your reliability commitment. -- For client-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or search with a realistic `target_reliability`. -- For tail risk, trust `worst_day_loss`, not headline `total_sla`. -- Timescale mix (`β`) is derived from `r` (weights recent vs longer-term uptime in settlement). Hosts cannot set β via the listing API. -- **Backtester limits:** Multi-renter overlap on one machine may exceed simulated `worst_day_loss`. Pair this output with [SLA and GPU slicing](/host/sla-offers#sla-and-gpu-slicing) when several SLA contracts can run concurrently. +**Simulation limits** +- The whole machine is replayed as one contract. Live settlement runs per rental contract, so several concurrent SLA renters on a sliced machine can produce more credits on one day than the simulation shows. Pair this output with [SLA and GPU slicing](/host/sla-offers#sla-and-gpu-slicing). +- For renter-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or search with a realistic `target_reliability`. +- How recent versus long-term uptime is weighted is set automatically from the renter target. It is not a host setting; the value used is echoed in `params.beta`. ## Before you start -**Prerequisites:** API key with `machine_read` permission, machine ID from the [Host Machines page](https://cloud.vast.ai/host/machines), and `curl` (or Postman). On Windows, use WSL or Postman. This is the same numeric machine ID as `machid` on the earnings API and `machine` in listing requests. +**Prerequisites:** an API key with `machine_read` permission, your machine ID, and `curl` (or Postman). On Windows, use WSL or Postman. The machine ID is the same number as `machid` on the earnings API and `machine` in listing requests. 1. Open **Account → API Keys** in the console and create a key with **`machine_read`** enabled. -2. Copy the token and use `Authorization: Bearer YOUR_API_KEY` in the examples below. See [Create API Key](/api-reference/accounts/create-api-key) and [Authentication](/api-reference/authentication). -3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). The machine must have at least a few weeks of rental activity — new or idle machines should use the console **Set Pricing → SLA** preview instead (the backtester returns `has_data: false` without sufficient history). +2. Use `Authorization: Bearer YOUR_API_KEY` in the examples below. See [Create API Key](/api-reference/accounts/create-api-key) and [Authentication](/api-reference/authentication). +3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). New or idle machines should use the console **Set Pricing → SLA** preview instead (the backtester returns `has_data: false` without rental history). 4. Run the baseline request in [Example request](#example-request) and check `has_data` in the response. ## API reference -The backtester is available through the REST API only. You must own the machine and use an API key with **`machine_read`** permission. Python SDK (`vastai` package) support is not yet available — use the `curl` examples below. +The backtester is available through the REST API only, for hosts. You must own the machine and use an API key with **`machine_read`** permission. The Python SDK does not support the backtester; use the `curl` examples below. ``` GET /api/v0/host/sla_backtest/ ``` -Clients that normalize URLs may also accept the form without a trailing slash; prefer the OpenAPI path above. - -Requires Bearer authentication. This endpoint is rate-limited like other host API endpoints — see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) for retry guidance. +Requires Bearer authentication. Rate-limited to about one request every two seconds (`x-rate-limit` threshold `2.0`); see [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ### Query parameters | Parameter | Required | Description | | --- | --- | --- | | `machine_id` | Yes | ID of your machine | -| `r` | Yes | Reliability level to simulate (greater than 0 and at most **0.9999**). Used as **both reliability commitment and client target** in the simulation. Example: `0.95` = 95%. Exactly `1.0` is rejected. | -| `p` | No | Host confidence (greater than 0 and **less than 1** — not equal to 1). Maps to the same spread used when listing with `sla_sigma_x` — see [Confidence values](#confidence-values-p) below. Default: `0.6667` (normal confidence, ≈ 67%). | +| `r_claim` | Yes | Reliability commitment to simulate (the `sla_r_claim` you plan to list), greater than 0 and at most `0.99999`. Example: `0.99` = 99%. | +| `p` | No | Host confidence, greater than 0 and less than 1. Uses a different scale from listing `sla_sigma_x` — see [Confidence values](#confidence-values-p). Default: `0.6667` (Normal). | +| `r_target` | No | Renter reliability target to simulate. Must be greater than 0 and at most `r_claim`. Default: `r_claim`. | | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | -| `reliability` | No | Optional flat uptime override (greater than 0 and at most 1). Ignores historical uptime — useful for what-if analysis. Use `0.01` to approximate near-total downtime; `0` is rejected with `400 bad_request`. | -| `beta` | No | Not user-configurable — omit it. The API derives timescale weighting from `r` and echoes the value used in `params.beta` (the sample response shows `0.5`). Do not send a constant default. | + +Any other query parameter is rejected with `400 bad_request`. The older `r` and `reliability` parameters are no longer accepted; use `r_claim` (and `r_target`). ### Limits @@ -103,92 +97,76 @@ Requires Bearer authentication. This endpoint is rate-limited like other host AP | Default lookback | 90 days | | Maximum range | 366 days (inclusive) | | Ownership | Must own the machine | -| Rate limits | Per-endpoint; see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) | +| Rate limit | About one request every two seconds | ### Example request -Minimal baseline (default 90-day lookback — no custom dates required): +Baseline (default 90-day lookback, renter target = your commitment): ```bash curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.6667" ``` -Custom date range (optional — relative UTC window): +Model renters who choose a 95% target against your 99% commitment: ```bash -# Example window: last ~90 days ending now (Linux GNU date) -# Linux: start=$(date -u -d '90 days ago' +%s); end=$(date -u +%s) -# macOS: start=$(date -u -v-90d +%s); end=$(date -u +%s) -start=$(date -u -d '90 days ago' +%s) -end=$(date -u +%s) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.95&p=0.6667&start_date=$start&end_date=$end" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&r_target=0.95&p=0.6667" ``` -Compare two confidence levels on the same history: +Custom date range: ```bash -# Normal confidence (~67%, default 0.6667) -curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667" - -# Tight (~83%) — tighter spread, lower simulated SLA charges +# Linux (GNU date). macOS: start=$(date -u -v-90d +%s) +start=$(date -u -d '90 days ago' +%s) +end=$(date -u +%s) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.83" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.6667&start_date=$start&end_date=$end" ``` -Stress-test with flat 90% uptime: +Compare two confidence levels on the same history: ```bash +# Normal (default 0.6667) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r=0.99&p=0.6667&reliability=0.90" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.6667" + +# Tight (0.83): lower SLA fees for renters, same credit rules +curl -s -H "Authorization: Bearer YOUR_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.83" ``` ## Reading the response -**If you only read three fields:** Check `has_data` (widen dates if `false`), then `summary.worst_day_loss`, then `summary.total_sla`. +**If you only read three things:** check `has_data` (widen dates if `false`), compare `r_eff` with `r_be`, then look at your [net SLA result and largest single-day credit](#summarize-with-jq). -A successful response looks like this (fields abbreviated; counts are illustrative—`covered_days` and `skipped_days` need not be equal): +A successful response looks like this (one `days` row shown; values are illustrative): ```json { "success": true, "machine_id": 12345, "has_data": true, - "start_day": 19723, - "end_day": 19812, - "covered_days": 60, - "skipped_days": 30, - "reliability": 0.998500, - "fleet_reliability": 0.991200, - "params": { - "r": 0.95, - "p": 0.6667, - "sigma_x": 0.5, - "reliability": null, - "beta": 0.5 - }, - "daily_results": [ + "start_day": 20568, + "end_day": 20657, + "r_eff": 0.9987, + "r_be": 0.9712, + "days": [ { - "day": 19723, - "gpu": 84.0, - "storage": 2.4, - "bandwidth": 0.1, - "uptime": 1.0, - "sla": 0.18, - "historical_sla": 0.0 + "day": 20568, + "client_compute_to_escrow": 78.12, + "client_premium_to_escrow": 0.19, + "escrow_to_client_balance": 0.0, + "escrow_to_host_balance": 76.4, + "reliability": 1.0 } ], - "summary": { - "total_gpu": 3780.0, - "total_storage": 108.0, - "total_bandwidth": 4.5, - "total_sla": 8.1, - "total_earnings": 3900.6, - "total_historical_sla": 0.0, - "worst_day_loss": 42.0, - "reserve": 0.0 + "params": { + "r_claim": 0.99, + "r_target": 0.99, + "beta": 0.5, + "p": 0.6667 } } ``` @@ -197,169 +175,160 @@ A successful response looks like this (fields abbreviated; counts are illustrati | Field | Meaning | | --- | --- | -| `has_data` | `true` if at least one day in the range had earnings to replay. When `false`, there was no billable rental activity in the range: `covered_days` is `0`, `skipped_days` equals the number of days in the requested window, `daily_results` contains one zero-filled row per day in the window (not an empty array), summary totals are `0.0`, and top-level `reliability` is `null`. Try a wider window or a machine with more rental history. | -| `start_day`, `end_day` | UTC day indices. The API computes `day = floor(epoch_seconds / 86400)`. Same encoding as `daily_results[].day`. `day × 86400` is exactly 00:00 UTC on that date. Convert with `date -u -d "@$((day * 86400))" +%F` (Linux) or `date -u -r $((day * 86400)) +%F` (macOS). Show Earnings `sday` / `eday` use the same day index. Most hosts can ignore these and use `start_date`/`end_date` in requests. | -| `covered_days` | Days with rental activity replayed through SLA math | -| `skipped_days` | Days in the range with no activity (zero-filled in `daily_results`) | -| `reliability` | Actual uptime ratio over the range (`total uptime / total active time`) | -| `fleet_reliability` | Average reliability across your machines (including this one). Context only; may be uninformative if you operate a single machine. | - -### Per-day fields (`daily_results`) +| `has_data` | `true` if the range had at least one day of rental earnings to replay. When `false`, every `days` row is zero with `reliability: null`, and `r_eff` is `null`. Try a wider window or a machine with more rental history. | +| `start_day`, `end_day` | UTC day indices, `day = floor(epoch_seconds / 86400)`. `day × 86400` is exactly 00:00 UTC on that date. Convert with `date -u -d "@$((day * 86400))" +%F` (Linux) or `date -u -r $((day * 86400)) +%F` (macOS). Show Earnings `sday` / `eday` use the same day index. | +| `r_eff` | **Effective reliability**: the constant reliability that would have produced the service credits paid in this window. `null` when the window had no deposits. | +| `r_be` | **Break-even reliability**: the reliability at which SLA fees and service credits cancel out. Always present. | +| `days` | One row per UTC day from `start_day` to `end_day` (see below). | +| `params` | The SLA terms the replay actually used: `r_claim`, `r_target` (after defaulting), `p`, and the automatically derived `beta`. | -| Field | Meaning | -| --- | --- | -| `gpu`, `storage`, `bandwidth` | That day's compute earnings breakdown ($) | -| `uptime` | Uptime fraction for the day (0–1), or your flat override if set | -| `sla` | **Simulated SLA host earnings** for the day. Positive = you keep the SLA charge; negative = you credit the client | -| `historical_sla` | What you **actually** earned from SLA that day (signed). Zero if you were not offering SLA | +**`r_eff` vs `r_be`:** if `r_eff` is above `r_be`, SLA would have been net positive for you over this window (fees exceeded credits). If it is below, SLA would have cost you money. The gap tells you how much reliability headroom you had. -Review `sla` day by day in `daily_results` to see which days would have helped or hurt under the chosen parameters. Compare against `historical_sla` to see how simulated economics differ from reality. +### Per-day fields (`days`) -### Summary fields +Every value is money (in $) that moved on that day. All flows are zero or positive. | Field | Meaning | | --- | --- | -| `total_gpu`, `total_storage`, `total_bandwidth` | Compute earnings over covered days | -| `total_sla` | Net simulated SLA earnings. Positive = SLA would have added income overall | -| `total_earnings` | Compute + simulated SLA | -| `total_historical_sla` | Sum of realized historical SLA in the range | -| `worst_day_loss` | Largest single-day client credit (your worst simulated loss). Always a non-negative dollar amount — unlike signed `sla` / `sla_earn` fields | -| `reserve` | Reserved for future use — ignore in production decisions today. | +| `day` | UTC day index | +| `client_compute_to_escrow` | The renter's compute payment for the day, held in escrow (your net earnings after the platform fee) | +| `client_premium_to_escrow` | The SLA fee paid in for the day | +| `escrow_to_client_balance` | Service credits paid to the renter that day | +| `escrow_to_host_balance` | Money released from escrow to you that day | +| `reliability` | Measured uptime fraction for the day (0–1), or `null` when the machine had no rental data that day | -## Interpreting results +Releases to you are spread over time rather than paid out the same day, and the final active day includes the contract's closing settlement. Read individual days as cash movement, not as that day's profit or loss. -### Mostly positive `sla` values +### Summarize with jq -Your historical reliability was strong relative to the simulated target. SLA would likely have been a net positive — small SLA charges on strong days, few days with credits. +```bash +curl -s -H "Authorization: Bearer YOUR_API_KEY" \ + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&r_target=0.95&p=0.6667" \ + | jq '{has_data, r_eff, r_be, + sla_fees: ([.days[].client_premium_to_escrow] | add), + credits: ([.days[].escrow_to_client_balance] | add), + net_sla: (([.days[].client_premium_to_escrow] | add) - ([.days[].escrow_to_client_balance] | add)), + largest_day_credit: ([.days[].escrow_to_client_balance] | max)}' +``` + +- **`net_sla`** — SLA fees minus service credits over the window. Positive means SLA would have added income. +- **`largest_day_credit`** — the most credit paid out on any single day. Use it as your single-day tail-risk reference (the last active day can be larger because it includes the closing settlement). + +## Interpreting results -### Negative `sla` on specific days +### `r_eff` well above `r_be` -Those days had reliability below the simulated target. The magnitude shows how much you would have credited. If you see clusters of negative days, consider a lower reliability commitment, wider confidence, or fixing reliability before listing SLA. +Your historical reliability was strong relative to the simulated target. SLA would likely have been net positive: small fees on most days and few credits. -### `total_sla` near zero +### `r_eff` close to `r_be` -Break-even territory — SLA charges and credits roughly balance. Typical when your actual reliability matches the simulated target. +Break-even territory: fees and credits roughly balance. A few bad days would tip you negative. -### `total_sla` strongly negative +### `r_eff` below `r_be` -Under the simulated parameters, SLA would have cost you money over this window. Either improve reliability, lower the reliability commitment, or widen confidence before listing. +Under these terms, SLA would have cost you money over this window. Improve reliability, lower your reliability commitment, or choose wider confidence before listing. -### Using `reliability` override +### Large `largest_day_credit` -Setting `reliability=0.90` while keeping `r=0.99` answers: *if every active day had 90% uptime, how bad would SLA credits get?* Use this to understand worst-case credit exposure before committing to a high reliability commitment. +A single outage day can cost far more than many days of fees. Check that you can absorb this amount, and remember it is a machine-level figure: concurrent SLA renters on a sliced machine can add up to more. ## Confidence values (`p`) -**`p` and `sla_sigma_x` use different scales** — do not copy numeric values between them. For example, `p=0.5` (wide confidence) maps to `sla_sigma_x ≈ 1.0`, not `0.5`. Use the table below to translate between the two. +**`p` and `sla_sigma_x` use different scales** — do not copy numeric values between them. For example, `p=0.5` (Wide) maps to `sla_sigma_x ≈ 1.0`, not `0.5`. Use the table below to translate between the two. -The backtester accepts **`p`** (confidence) instead of `sla_sigma_x`. The mappings below match common listing values: - -| Confidence `p` | Approx. label | Listing equivalent | +| Confidence `p` | Console label | Listing equivalent | | --- | --- | --- | | `0.83` | Tight | `sla_sigma_x ≈ 0.2` | | `0.6667` | Normal (default) | `sla_sigma_x ≈ 0.5` | | `0.50` | Wide | `sla_sigma_x ≈ 1.0` | -Tighter confidence (higher `p`) does **not** reduce credit owed on a miss — use `worst_day_loss` and `reliability=` overrides to model settlement exposure. +Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** reduce the credit owed on a miss. ## Error responses -| HTTP | `error` / shape | Cause | +| HTTP | `error` | Cause | | --- | --- | --- | -| 400 | `invalid_range` | Date window invalid | -| 400 | `range_too_large` | Window exceeds the maximum span | -| 400 | `bad_request` | Out-of-range `r`, `p`, or date parameters | -| 400 | `invalid_params` | Simulation math failure after validation (check the reliability commitment/confidence inputs) | -| 403 | `not_owner` | Machine belongs to another host | +| 400 | `bad_request` | Missing `r_claim`, an out-of-range value, or an unknown parameter (for example the old `r` or `reliability`) | +| 400 | `invalid_params` | The SLA terms don't combine, for example `r_target` greater than `r_claim` | +| 400 | `invalid_range` | `start_date` is after `end_date` | +| 400 | `range_too_large` | The window is longer than 366 days | +| 401 | — | Missing or invalid API key, or the key lacks `machine_read`. See [Authentication](/api-reference/authentication). | +| 403 | `not_owner` | The machine belongs to another host | +| 403 | `sla_disabled` | SLA is not currently enabled on the platform. Try again later or contact support. | | 404 | `machine_not_found` | Invalid `machine_id` | -| 429 | *(rate limited)* | Too many requests — retry with backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | - -For missing or invalid API keys and permission denials (`machine_read`), see [Authentication](/api-reference/authentication). +| 429 | — | Too many requests. Wait at least two seconds and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | ## Recommended workflow -1. **Run a baseline backtest** on a machine with at least a few weeks of rental history: - - Check your machine's uptime history on the [Host Machines page](https://cloud.vast.ai/host/machines), then use the console SLA preview or backtester — do not rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). - - Choose an `r` at or slightly below the reliability commitment you plan to publish. - - Use normal confidence (`p=0.6667`). - - If `has_data` is `false`, widen the date range or wait for more rental history. -2. **Check `worst_day_loss`** — can you absorb that credit from a bad day? -3. **Try a higher `r`** (for example `0.99`) and see how `total_sla` changes. -4. **Run a stress test** with `reliability=0.90` at your intended reliability commitment. -5. **List with `sla_r_claim`** — set the reliability commitment (and `sla_sigma_x`) on the offer; clients choose their own targets in search (see [SLA Offers](/host/sla-offers)). +1. **Run a baseline** on a machine with at least a few weeks of rental history, with `r_claim` set to the commitment you plan to list and `p=0.6667`. If `has_data` is `false`, widen the date range or wait for more history. Don't rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). +2. **Compare `r_eff` with `r_be`** to see whether you had headroom. +3. **Add `r_target`** at the targets renters are likely to choose (for example `0.95`) and compare `net_sla`. +4. **Check `largest_day_credit`** — can you absorb that from one bad day? +5. **List with `sla_r_claim`** and `sla_sigma_x` on the offer; renters choose their own targets in search (see [SLA Offers](/host/sla-offers)). ## Fleet workflow -**Console-only hosts: stop here** — use **Set Pricing → SLA** on [SLA Offers](/host/sla-offers#web-console) instead of this loop. - -Optional. Skip this section unless you automate many machines. Console hosts can use **Set Pricing → SLA** and a single request instead of the loop below. +Optional, for API automation only. To check one machine, use the single-machine request above. **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). -```bash -export VAST_API_KEY="YOUR_API_KEY" -``` - -1. List machine IDs: `vastai show machines -q` (numeric IDs only) or `vastai show machines --raw | jq -r '.machines[].id'`. -2. Run backtests **sequentially** (one machine at a time). Set `r` to each machine’s **candidate** reliability commitment (the `sla_r_claim` you plan to list)—do not assume a fleet-wide `0.95` if you intend to list at `0.99` or another value. Write responses under a private temp dir (not world-readable `/tmp` paths on shared hosts) and delete them when done: +1. Run backtests **sequentially**, one machine at a time. The loop reads each machine's `sla_r_claim` and `sla_sigma_x`. For machines that don't have SLA yet, set `R` (commitment) and `P` (confidence `p`) to backtest them before you enable SLA. Machines with neither are skipped and logged. +2. Responses are written to a private temp directory that is deleted when the loop exits. ```bash -# Prefer each machine's planned sla_r_claim / sla_sigma_x from show machines --raw. -# Uniform r override: export R=0.99. Map sla_sigma_x → p via Confidence values table. +export VAST_API_KEY="YOUR_API_KEY" +# Optional overrides for machines without SLA yet: R=0.99 P=0.6667 (Normal). BT_DIR=$(mktemp -d) trap 'rm -rf "$BT_DIR"' EXIT machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do - r="${R:-}" machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') - if [ -z "$r" ]; then - r=$(echo "$machine" | jq -r '.sla_r_claim // empty') - fi + r="${R:-$(echo "$machine" | jq -r '.sla_r_claim // empty')}" if ! jq -e -n --arg r "$r" 'try (($r | tonumber) > 0) catch false' >/dev/null 2>&1; then - echo "skip $id: set Claim (reliability commitment, sla_r_claim) in console (**Set Pricing → SLA**) or export R=0.99"; continue + echo "skip $id: no sla_r_claim; set R=0.99 (or your planned commitment) to backtest before enabling SLA"; continue fi - if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then - echo "skip $id: set Confidence in console or PUT sla_sigma_x before backtest"; continue + p="${P:-}" + if [ -z "$p" ]; then + if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then + echo "skip $id: no sla_sigma_x; set P=0.6667 (Normal) to backtest before enabling SLA"; continue + fi + # Map sla_sigma_x to the nearest p band: Tight 0.2 -> 0.83, Normal 0.5 -> 0.6667, Wide 1.0 -> 0.50. + p=$(echo "$machine" | jq -r '.sla_sigma_x as $s + | if $s <= 0.35 then 0.83 elif $s <= 0.75 then 0.6667 else 0.50 end') fi - # Approx bands from Confidence values (p): Tight≈0.2 → 0.83, Normal≈0.5 → 0.6667, Wide≈1.0 → 0.50. - # Non-table sla_sigma_x values map to the nearest band; for custom spreads, pass p explicitly. - p=$(echo "$machine" | jq -r ' - .sla_sigma_x as $s - | if $s <= 0.35 then 0.83 - elif $s <= 0.75 then 0.6667 - else 0.50 end') out="$BT_DIR/sla_bt_$id.json" http=$(curl -s -o "$out" -w "%{http_code}" \ -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r=$r&p=$p") + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r_claim=$r&p=$p") if [ "$http" != "200" ] || ! jq -e '.success == true' "$out" >/dev/null 2>&1; then echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' "$out" 2>/dev/null)" - sleep 2; continue + sleep 3; continue fi - jq -c --arg id "$id" --argjson r "$r" --argjson p "$p" \ - '{machine_id: $id, r: $r, p: $p, worst_day_loss: .summary.worst_day_loss, total_sla: .summary.total_sla, has_data: .has_data}' \ - "$out" - sleep 2 + jq -c --arg id "$id" '{machine_id: $id, params, has_data, r_eff, r_be, + net_sla: (([.days[].client_premium_to_escrow] | add) - ([.days[].escrow_to_client_balance] | add)), + largest_day_credit: ([.days[].escrow_to_client_balance] | max)}' "$out" + sleep 3 done ``` -Expect roughly two seconds per machine minimum (`sleep 2` plus request time). For 50 machines, budget at least a few minutes. Run off-peak before a fleet SLA rollout. This example logs failure and continues after one attempt; on HTTP **429**, wait and retry that machine with backoff before treating it as failed—a single burst can otherwise skip healthy machines. Parallel requests are not recommended unless you implement backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). +Expect about three seconds per machine (`sleep 3` plus request time), so budget a few minutes for 50 machines. The example logs a failure and moves on after one attempt. On HTTP **429**, wait and retry that machine before treating it as failed. Don't run requests in parallel unless you implement backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). -3. Compare `worst_day_loss` and `total_sla` across machines at the **`r` each will list** (or at one shared `R` if the fleet is uniform). +3. Compare `r_eff`, `r_be`, `net_sla`, and `largest_day_credit` across machines. 4. Apply matching `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). ## When stuck - **`has_data: false`** — Widen the date range or wait for rental history. -- **`401`** — Check API key permissions (`machine_read`) and Bearer header format. +- **`400 bad_request` on a request that used to work** — Replace `r=` with `r_claim=` and remove `reliability=`. +- **`401`** — Check API key permissions (`machine_read`) and the Bearer header format. - **Still stuck** — Ask in the [host Discord](https://discord.gg/hSuEbSQ4X8). ## Related documentation - [SLA Backtest API](/api-reference/host/sla-backtest) — formal API reference for this endpoint - [SLA Offers](/host/sla-offers) — listing parameters, economics, and risk scenarios -- [SLA (renters)](/guides/instances/choosing/sla-coverage) — how renters (clients) choose targets and read `dph_total` +- [SLA (renters)](/guides/instances/choosing/sla-coverage) — how renters choose targets and read `dph_total` - [API permissions](/api-reference/permissions) — `machine_read` scope required diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a1697824..64b45fd7 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -75,7 +75,7 @@ On outage days you may still bill clients for **intended** compute **and** owe s - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. -- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting `worst_day_loss`. Consider wider confidence or a more conservative reliability commitment until you have a few weeks of data. +- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting backtester results. Consider wider confidence or a more conservative reliability commitment until you have a few weeks of data. ## SLA in plain language @@ -122,7 +122,7 @@ When a client rents an on-demand instance on your SLA-listed offer with a chosen - **Strong reliability relative to the client's target** → you keep the SLA charge for that day. - **Shortfalls** → credits flow to the client from your earnings (bounded by that day's covered compute). -Over many strong days, SLA charges can offset occasional credits, but a single bad day can exceed months of collected charges — see [Risk scenarios](#risk-scenarios) and `worst_day_loss` before you commit. +Over many strong days, SLA charges can offset occasional credits, but a single bad day can exceed months of collected charges — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. ### How reliability is measured @@ -145,7 +145,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | -| Reliability commitment | `sla_r_claim` | `r` (backtester sets the reliability commitment = target = `r`) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | +| Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | | Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA charges for clients at a given target). Defaults to `0.5` if omitted. | ### Advanced: `sla_max_beta` (optional) @@ -161,9 +161,9 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Concept | Console | Listing API | Backtester | Client sees / sets | | --- | --- | --- | --- | --- | -| Reliability commitment | Claim | `sla_r_claim` | `r` (claim = target in sim) | `expected_reliability` | +| Reliability commitment | Claim | `sla_r_claim` | `r_claim` | `expected_reliability` | | Confidence | Confidence / spread | `sla_sigma_x` | `p` (different scale) | — | -| Reliability target | — (client-chosen) | — (not on asks) | `r` (same as claim in sim) | `target_reliability` in search | +| Reliability target | — (client-chosen) | — (not on asks) | `r_target` (optional; defaults to `r_claim`) | `target_reliability` in search | | All-in hourly price | — | — | — | `dph_total` (compute plus SLA charge when enabled) | **Confidence is not an uptime target.** It controls how aggressively SLA charges are priced around your reliability commitment. @@ -176,7 +176,7 @@ The **reliability score** on the Host Machines page reflects connection and inst Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r_claim`: 1. Open **Host → Machines** → **Set Pricing → SLA** and review the console SLA charge preview at candidate reliability commitments. -2. If you have rental history, run the [backtester](/host/sla-backtester) and check top-level `reliability` in the response. +2. If you have rental history, run the [backtester](/host/sla-backtester) and compare `r_eff` (effective reliability) with `r_be` (break-even reliability) in the response. 3. Set **reliability commitment** at a level you can sustain; clients who pick targets below your reliability commitment see lower SLA charges. ### Confidence values @@ -191,7 +191,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r **Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). -**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA charges (more competitive `dph_total`). **Wider confidence** (console label **Wide**) → higher client SLA charges. Confidence does **not** change the credit formula when a target is missed — use `worst_day_loss` and stress-test with the backtester `reliability=` override for tail-risk planning. +**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA charges (more competitive `dph_total`). **Wider confidence** (console label **Wide**) → higher client SLA charges. Confidence does **not** change the credit formula when a target is missed — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. ### Validation rules @@ -209,9 +209,9 @@ If listing is rejected with `error: "invalid_sla_params"`, check the `msg` field SLA settlement applies per rental contract. If your machine has multiple GPU slices rented by different clients (GPU slicing — see **Min GPU** in [Hosting Overview](/host/hosting-overview)), each contract's SLA is settled independently based on the reliability experienced by that instance. -The backtester replays **machine-level** daily earnings (total compute across all active rentals on that machine). `worst_day_loss` in `summary` reflects the worst simulated day for the whole machine in the replay window — not a single GPU slice in isolation. +The backtester replays **machine-level** daily earnings (total compute across all active rentals on that machine). Its largest single-day credit reflects the worst simulated day for the whole machine in the replay window — not a single GPU slice in isolation. -If multiple on-demand SLA contracts can be active on one machine at once, a single outage may trigger service credits **per contract**. The backtester’s `worst_day_loss` reflects machine-level replay for one simulated day—it may not equal the sum of worst-case credits across concurrent SLA renters. For sliced hosts, stress-test with your expected concurrent SLA contract count or treat `worst_day_loss` as a **lower bound** until you confirm aggregation with support. Do **not** naively multiply `worst_day_loss` by contract count as a substitute for that check—the backtester already models machine-level compute for the replay window, but live per-contract settlement can still stack differently than one simulated day. +If multiple on-demand SLA contracts can be active on one machine at once, a single outage may trigger service credits **per contract**. The backtester’s largest single-day credit reflects a machine-level replay as one contract—it may not equal the sum of worst-case credits across concurrent SLA renters. For sliced hosts, treat it as a **lower bound** until you confirm aggregation with support. Do **not** naively multiply it by contract count as a substitute for that check—the backtester already models machine-level compute for the replay window, but live per-contract settlement can still stack differently than one simulated day. ### SLA on extended contracts @@ -487,12 +487,12 @@ SLA field updates apply to the **offer** and to **new** rentals only. Existing r | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr GPU only — simplified) | | SLA charge (client pays) | ~**$0.008/hr** (~$0.20/day at 24 hr) | -SLA credits are capped relative to that UTC day's covered compute — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat `worst_day_loss` from the [SLA backtester](/host/sla-backtester) as the authoritative tail-risk figure before you list. +SLA credits are capped relative to that UTC day's covered compute — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat the [largest single-day credit](/host/sla-backtester#summarize-with-jq) from the SLA backtester as the authoritative tail-risk figure before you list. -SLA charge sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview worst single-day credit exposure (`worst_day_loss`), not exact client SLA charges. For authoritative client-visible charges, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers at a chosen `target_reliability` — not backtester `total_sla` when clients will rent below your reliability commitment. +SLA charge sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview single-day credit exposure (largest single-day credit) and break-even reliability (`r_be`), not exact client SLA charges. For authoritative client-visible charges, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers at a chosen `target_reliability`. -The backtester sets the reliability commitment equal to target (`r`), which is a **conservative** what-if (as if every client targeted your reliability commitment). Live clients who choose targets **below** your reliability commitment usually see lower SLA charges than the backtester's simulated charges. Use `worst_day_loss` from the backtester as your worst single-day credit reference, then verify visible charges in **Set Pricing → SLA** (or `dph_total` in search) before listing. +If you omit `r_target`, the backtester sets the renter target equal to your reliability commitment (`r_claim`), which is a **conservative** what-if (as if every client targeted your reliability commitment). Pass `r_target` to model clients who choose lower targets; they usually see lower SLA charges. Use the backtester's largest single-day credit as your worst single-day credit reference, then verify visible charges in **Set Pricing → SLA** (or `dph_total` in search) before listing. ### Search / client-visible fields @@ -616,7 +616,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **Listing rejected (`invalid_sla_params`)** — Re-check the reliability commitment and `sla_sigma_x` against [validation rules](#validation-rules). - **`sla_not_approved`** — Contact support; you can keep a non-SLA listing while approval is pending. - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. -- **Unexpected credit** — Review reliability; re-run the backtester with a low `reliability` stress value (for example `0.01`). +- **Unexpected credit** — Review reliability; re-run the backtester over the affected dates and check `escrow_to_client_balance` and `reliability` on those days. - **Severe outage (active SLA contracts):** 1. Notify renters now: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS`. 2. Stop new SLA rentals. The fastest way is `vastai unlist machine MACHINE_ID`, which publishes nothing. Alternatively, set the reliability commitment to `0` in **Set Pricing → SLA** (or API `sla_r_claim=0`), but only on machines that are currently listed, because `create_asks` publishes a live listing. @@ -628,7 +628,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). -When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. Do not compare `per_day` totals to one machine’s backtester `worst_day_loss`. +When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. Do not compare `per_day` totals to one machine’s backtester largest single-day credit. ### Console (recommended for day-to-day checks) @@ -636,7 +636,7 @@ When you poll the API, use **`per_machine[].sla_earn`** for a single machine. ** 2. Set the date range to include the UTC day you want to review. 3. Filter by machine ID if available. 4. Look for **SLA** entries in the earnings breakdown — positive amounts are SLA charges you kept; negative amounts are credits you owed the client. -5. After downtime, compare the affected UTC day(s) to your `worst_day_loss` backtest estimate. +5. After downtime, compare the affected UTC day(s) to your backtester largest single-day credit. **If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). @@ -660,7 +660,7 @@ vastai show earnings --machine_id --start_date "$(date -u -v-7d +%F)T00:00: Keep the `T00:00:00Z` suffix: the CLI parses bare dates such as `2026-07-24` in your machine's local time, so append `T00:00:00Z` for an exact UTC day. On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. -**Linux (GNU date) — one UTC day (compare to `worst_day_loss`):** +**Linux (GNU date) — one UTC day (compare to the backtester largest single-day credit):** ```bash # Replace 12345 with your machine ID. @@ -694,7 +694,7 @@ This endpoint is rate-limited. Poll `GET /api/v0/users/{user_id}/machine-earning When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs backtester `worst_day_loss`), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +- **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs the backtester largest single-day credit), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. - **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window. @@ -726,9 +726,9 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` -Do **not** compare `last_days=7` totals to single-day `worst_day_loss` from the backtester. +Do **not** compare `last_days=7` totals to the backtester's largest single-day credit. -**Sign convention** (same as backtester `sla` / `historical_sla`): +**Sign convention:** | Field | Strong day (meet client target) | Weak day (miss client target) | | --- | --- | --- | From 7a4362cf17e49a477b3bade612c72d6942f85739 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 16:50:01 -0700 Subject: [PATCH 144/250] docs(sla): address doc-review consensus (cycle 95) Fix three contract errors confirmed against code and production: search rejects target_reliability as {"eq": ...} with 400 (send a plain number; the CLI cannot quote the SLA fee today), show machines returns listed_gpu_cost / listed_min_gpu_count / sla_reliability_claim / sla_confidence (so both fleet loops skipped every machine), and schedule maint fails without --maintenance_category. The re-list loop now skips unlisted machines via the listed field and omits sla_sigma_x so each machine keeps its exact confidence. Co-Authored-By: Claude Opus 5.5 (1M context) --- api-reference/openapi.yaml | 83 ++++++++++++------- api-reference/openapi/yaml/search_offers.yaml | 4 +- api-reference/openapi/yaml/show_machines.yaml | 45 ++++++---- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 10 ++- guides/instances/choosing/sla-coverage.mdx | 13 +-- host/sla-backtester.mdx | 19 +++-- host/sla-offers.mdx | 39 ++++----- snippets/host/cli/schedule-maint.mdx | 6 +- 9 files changed, 132 insertions(+), 89 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index ab560992..2d063d2b 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6661,13 +6661,14 @@ paths: description: 'Historical machine reliability score (0-1), not the host reliability commitment. Example: {"gte": 0.99}' target_reliability: - type: object + type: number description: "Reliability target for an SLA. Value must be greater\ \ than 0 and less than 1 (exclusive bounds \u2014\nsame as create-instance).\ \ When set, search prices include the SLA fee in dph_total and\n\ returns search.slaPremiumPerHour (the API name for that fee).\ \ Pass the same target again on PUT /api/v0/asks/{id}/ to\nenable\ - \ the SLA. Example: {\"eq\": 0.95}\n" + \ the SLA. Send a plain number (for example 0.95); an operator\ + \ object such as {\"eq\": 0.95} is rejected with 400 bad_request.\n" has_sla: type: object description: 'Restrict to offers with SLA enabled (true) or without @@ -8985,38 +8986,64 @@ paths: name: type: string description: The name of the machine. - price_gpu: - type: number - description: GPU rental price in $/hour (when present in - raw listing output). + listed: + type: boolean + description: true when the machine currently has a published + offer. + listed_gpu_cost: + type: + - number + - 'null' + description: Listed GPU price in $/hour (`price_gpu` on + create_asks). null when not listed. end_date: - type: number - description: Offer expiration as Unix timestamp (when present - in raw listing output). - min_chunk: - type: integer - description: Minimum GPUs rented together (GPU slicing). - sla_r_claim: - type: number - description: Host reliability claim. Values above 0 mean - SLA is enabled on the ask. - sla_sigma_x: - type: number - description: SLA confidence spread around the claim. - sla_max_beta: - type: number - description: "Optional cap on client-derived \u03B2 for\ - \ this ask (support-directed). Hosts do not\nset \u03B2\ - ; leave unset for uncapped.\n" + type: + - number + - 'null' + description: Offer expiration as Unix timestamp. null when + not listed. + listed_min_gpu_count: + type: + - integer + - 'null' + description: Minimum GPUs rented together (`min_chunk` on + create_asks). + sla_reliability_claim: + type: + - number + - 'null' + description: 'Host reliability commitment (`sla_r_claim` + on create_asks). Values above 0 mean SLA + + is enabled. null unless the machine is listed with SLA + terms. + + ' + sla_confidence: + type: + - string + - 'null' + enum: + - high + - medium + - low + description: 'Confidence band for the ask''s `sla_sigma_x`: + high = Tight (sigma_x <= 0.32), + + medium = Normal (<= 0.71), low = Wide. null unless the + machine is listed with SLA terms. + + ' example: machines: - id: '12345' name: my-h100 - price_gpu: 3.5 + listed: true + listed_gpu_cost: 3.5 end_date: 1735689600 - min_chunk: 1 - sla_r_claim: 0.99 - sla_sigma_x: 0.5 + listed_min_gpu_count: 1 + sla_reliability_claim: 0.99 + sla_confidence: medium '401': description: Unauthorized - User authentication failed '429': diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index d5281d50..368a2453 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -90,12 +90,12 @@ paths: type: object description: 'Historical machine reliability score (0-1), not the host reliability commitment. Example: {"gte": 0.99}' target_reliability: - type: object + type: number description: | Reliability target for an SLA. Value must be greater than 0 and less than 1 (exclusive bounds — same as create-instance). When set, search prices include the SLA fee in dph_total and returns search.slaPremiumPerHour (the API name for that fee). Pass the same target again on PUT /api/v0/asks/{id}/ to - enable the SLA. Example: {"eq": 0.95} + enable the SLA. Send a plain number (for example 0.95); an operator object such as {"eq": 0.95} is rejected with 400 bad_request. has_sla: type: object description: | diff --git a/api-reference/openapi/yaml/show_machines.yaml b/api-reference/openapi/yaml/show_machines.yaml index d0d56e5e..91a3cb91 100644 --- a/api-reference/openapi/yaml/show_machines.yaml +++ b/api-reference/openapi/yaml/show_machines.yaml @@ -39,35 +39,44 @@ paths: name: type: string description: The name of the machine. - price_gpu: + listed: + type: boolean + description: true when the machine currently has a published offer. + listed_gpu_cost: type: number - description: GPU rental price in $/hour (when present in raw listing output). + nullable: true + description: Listed GPU price in $/hour (`price_gpu` on create_asks). null when not listed. end_date: type: number - description: Offer expiration as Unix timestamp (when present in raw listing output). - min_chunk: + nullable: true + description: Offer expiration as Unix timestamp. null when not listed. + listed_min_gpu_count: type: integer - description: Minimum GPUs rented together (GPU slicing). - sla_r_claim: - type: number - description: Host reliability claim. Values above 0 mean SLA is enabled on the ask. - sla_sigma_x: - type: number - description: SLA confidence spread around the claim. - sla_max_beta: + nullable: true + description: Minimum GPUs rented together (`min_chunk` on create_asks). + sla_reliability_claim: type: number + nullable: true + description: | + Host reliability commitment (`sla_r_claim` on create_asks). Values above 0 mean SLA + is enabled. null unless the machine is listed with SLA terms. + sla_confidence: + type: string + nullable: true + enum: [high, medium, low] description: | - Optional cap on client-derived β for this ask (support-directed). Hosts do not - set β; leave unset for uncapped. + Confidence band for the ask's `sla_sigma_x`: high = Tight (sigma_x <= 0.32), + medium = Normal (<= 0.71), low = Wide. null unless the machine is listed with SLA terms. example: machines: - id: "12345" name: my-h100 - price_gpu: 3.5 + listed: true + listed_gpu_cost: 3.5 end_date: 1735689600 - min_chunk: 1 - sla_r_claim: 0.99 - sla_sigma_x: 0.5 + listed_min_gpu_count: 1 + sla_reliability_claim: 0.99 + sla_confidence: medium '401': description: Unauthorized - User authentication failed '429': diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 1ac3d4e0..b9c342be 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -164,7 +164,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings (console billing needs no API key; API earnings need `billing_read`). Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | -| Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=12345 verified=any has_sla=true target_reliability=0.95' --storage 10` (`verified=any` is often required when checking your own machine). | +| Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10` (`verified=any` is often required when checking your own machine). | Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index bd1c636c..1bdda1af 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -83,11 +83,15 @@ Filter examples (including SLA quotes) are under [Examples](#examples). Query sy # rented=false (excludes slots you already rent) is already in the CLI default query; shown here explicitly vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=false' -# SLA search quote (enable the SLA at rent via console/REST — see SLA) +# Find SLA offers (the CLI cannot quote the SLA fee today; see the Warning below) # Always set --storage explicitly when comparing dph_total (CLI default 5 GiB ≠ REST 8 GB). -vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 50 --order dph_total +vastai search offers 'has_sla=true expected_reliability>=0.99' --storage 50 --order dph_total ``` + +The current CLI cannot quote an SLA fee: it sends `target_reliability=0.95` as `{"eq": 0.95}`, which search rejects with `400 target_reliability: Input should be a valid number`. Use the CLI to find SLA offers (`has_sla`, `expected_reliability`), then get the SLA-inclusive `dph_total` from the console or REST (`"target_reliability": 0.95` as a plain number). + + **Next step for SLA:** Search only quotes SLA pricing. Enable SLA in the web console (**Reliability target** in **Search filters**, then **RENT**) or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. Do not use `vastai create instance` expecting SLA. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). @@ -194,7 +198,7 @@ bool = True | False SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. -The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": {"eq": 0.95}`. In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla`, `target_reliability`, and `expected_reliability`. The warning is harmless: the fields are still sent. To self-check, run `--raw | jq 'all(.[]; .expected_reliability > 0)'` (CLI `--raw` prints a bare array of offers, not an `offers` object). +The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": 0.95` (a plain number; `{"eq": 0.95}` is rejected with 400). In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla`, `target_reliability`, and `expected_reliability`. The warning is harmless: the fields are still sent. To self-check, run `--raw | jq 'all(.[]; .expected_reliability > 0)'` (CLI `--raw` prints a bare array of offers, not an `offers` object). ## Global Options diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index a46f23a6..385e7875 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -136,7 +136,7 @@ Console controls use the same concepts; they do not accept CLI query strings. Us | Filter | Meaning | Example (CLI / API) | | --- | --- | --- | -| `target_reliability` | Your desired reliability level. Also drives SLA charge calculation and ranking. | `target_reliability=0.95` | +| `target_reliability` | Your desired reliability level. Also drives SLA charge calculation and ranking. REST and console only (see the Warning below). | REST: `"target_reliability": 0.95` (plain number, not `{"eq": …}`) | | `has_sla` | Restrict to offers with (or without) SLA enabled. | `has_sla=true` | | `expected_reliability` | Filter by the host's advertised reliability commitment. | `expected_reliability>=0.99` | @@ -146,13 +146,14 @@ Console controls use the same concepts; they do not accept CLI query strings. Us **CLI examples:** + +The current CLI cannot quote an SLA fee: it sends `target_reliability=0.95` as `{"eq": 0.95}`, which search rejects with `400 target_reliability: Input should be a valid number`. Use the CLI to find SLA offers (`has_sla`, `expected_reliability`), then get the SLA-inclusive `dph_total` from the console or REST (`"target_reliability": 0.95` as a plain number). + + ```bash # SLA offers where the host's reliability commitment is at least 99% # Set --storage to match the disk you will rent (console often 10; REST often 8+) -vastai search offers 'has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10 - -# Compare total cost including SLA charge -vastai search offers 'has_sla=true target_reliability=0.95 num_gpus=1' --storage 10 --order dph_total +vastai search offers 'has_sla=true expected_reliability>=0.99' --storage 10 ``` When you set `target_reliability`, search results include: @@ -225,7 +226,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ "external": {"eq": false}, "allocated_storage": 50, "order": [["dph_total", "asc"]], - "target_reliability": {"eq": 0.95}, + "target_reliability": 0.95, "has_sla": {"eq": true}, "expected_reliability": {"gte": 0.99} }' diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index c472b755..1c6c7e84 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -274,7 +274,7 @@ Optional, for API automation only. To check one machine, use the single-machine **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). -1. Run backtests **sequentially**, one machine at a time. The loop reads each machine's `sla_r_claim` and `sla_sigma_x`. For machines that don't have SLA yet, set `R` (commitment) and `P` (confidence `p`) to backtest them before you enable SLA. Machines with neither are skipped and logged. +1. Run backtests **sequentially**, one machine at a time. The loop reads each machine's `sla_reliability_claim` and `sla_confidence` label from `show machines`. For machines that don't have SLA yet, set `R` (commitment) and `P` (confidence `p`) to backtest them before you enable SLA. Machines with neither are skipped and logged. The confidence label is a band, so a custom `sla_sigma_x` is backtested at the nearest band's `p`; set `P` to test an exact value. 2. Responses are written to a private temp directory that is deleted when the loop exits. ```bash @@ -286,18 +286,19 @@ machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') - r="${R:-$(echo "$machine" | jq -r '.sla_r_claim // empty')}" + r="${R:-$(echo "$machine" | jq -r '.sla_reliability_claim // empty')}" if ! jq -e -n --arg r "$r" 'try (($r | tonumber) > 0) catch false' >/dev/null 2>&1; then - echo "skip $id: no sla_r_claim; set R=0.99 (or your planned commitment) to backtest before enabling SLA"; continue + echo "skip $id: no sla_reliability_claim; set R=0.99 (or your planned commitment) to backtest before enabling SLA"; continue fi p="${P:-}" if [ -z "$p" ]; then - if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then - echo "skip $id: no sla_sigma_x; set P=0.6667 (Normal) to backtest before enabling SLA"; continue - fi - # Map sla_sigma_x to the nearest p band: Tight 0.2 -> 0.83, Normal 0.5 -> 0.6667, Wide 1.0 -> 0.50. - p=$(echo "$machine" | jq -r '.sla_sigma_x as $s - | if $s <= 0.35 then 0.83 elif $s <= 0.75 then 0.6667 else 0.50 end') + # show machines returns confidence as a label: high = Tight, medium = Normal, low = Wide. + case "$(echo "$machine" | jq -r '.sla_confidence // empty')" in + high) p=0.83 ;; + medium) p=0.6667 ;; + low) p=0.50 ;; + *) echo "skip $id: no sla_confidence; set P=0.6667 (Normal) to backtest before enabling SLA"; continue ;; + esac fi out="$BT_DIR/sla_bt_$id.json" http=$(curl -s -o "$out" -w "%{http_code}" \ diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 64b45fd7..5928a443 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -45,7 +45,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 7. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). 8. **First publish and verify:** **Save** pricing, then click **LIST** (first publish only). If the machine is already listed, **Save** alone updates the live offer. - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99 target_reliability=0.95' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). + - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). 9. **Self-test (after LIST):** With the separate client account from step 2, search by `machine_id`, rent with a **Reliability target**, and verify the SLA (billed like any rental)—see [Testing your own machine](/host/hosting-overview#testing-your-own-machine). ## Before you enable SLA @@ -322,12 +322,12 @@ Partial updates are supported when editing an existing listing. If you change on Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. Read current listing fields from `vastai show machines --raw`: ```bash -vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, sla_r_claim, sla_sigma_x, price_gpu, end_date}' +vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, listed, sla_reliability_claim, sla_confidence, listed_gpu_cost, listed_min_gpu_count, end_date}' ``` REST equivalent: `GET /api/v0/machines/?user_id={user_id}` (`user_id` is required). Get `user_id` from **Account → Profile** or `vastai show user`. The CLI supplies `user_id` for you. -Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. +Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence` (`high` = Tight, `medium` = Normal, `low` = Wide), not as `sla_sigma_x`. The SLA fields are `null` unless the machine is listed with SLA terms. Pricing fields and `end_date` are `null` when the machine is not listed. Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge → PUT). `vastai list machine` and the Python SDK listing helpers cannot set SLA fields; start from this REST pattern (or the console) when you move an existing CLI listing to SLA. @@ -338,12 +338,12 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge **Console hosts:** skip this section. Enable an SLA with [Web console](#web-console) and check settlement in [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). -Use this loop to republish SLA terms across a fleet, for example after a daemon update. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that already have `sla_r_claim > 0`. +Use this loop to republish SLA terms across a fleet, for example after a daemon update. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. -`create_asks` defaults `sla_sigma_x` to `0.5` when you omit it on a write. This guide does **not** treat a missing `sla_sigma_x` in `show machines --raw` as that default—the raw payload may omit the field even when you intend Normal confidence. The loop **skips and logs** those IDs so it never silently writes `0.5`. Set **Confidence** in the console (or PUT `sla_sigma_x` for that machine), then re-run. A skip is not “SLA-ready.” +`show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. -`PUT /api/v0/machines/create_asks/` **publishes a live listing** (same as **LIST**). A `sla_r_claim > 0` filter is **not** a listed-status check—running with `DRY_RUN=0` can put intentionally unlisted or paused machines back on the market. Before you apply, confirm each machine is **Listed** on **Host → Machines**. There is no documented `show machines --raw` listed flag; keep an allowlist (CSV: `machine_id`, `intended_listed`) and only automate IDs with `intended_listed=true`. +`PUT /api/v0/machines/create_asks/` **publishes a live listing** (same as **LIST**). The loop skips machines whose `listed` field is not `true`, so it does not republish machines you unlisted. Still keep an `ALLOWLIST` of the machine IDs you intend to automate, and confirm them on **Host → Machines** before you run with `DRY_RUN=0`. **Fleet operators only.** Do not run the loop unless you manage a fleet. @@ -351,7 +351,7 @@ Use this loop to republish SLA terms across a fleet, for example after a daemon -Validate `price_gpu`, `end_date`, and `min_chunk` before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. Expired offers (past `end_date`) are skipped so a re-list run does not unpublish live SLA listings. +Validate the listed price (`listed_gpu_cost`), `end_date`, and minimum GPU count (`listed_min_gpu_count`) before each PUT. Prefer reading existing SLA fields from each machine rather than hardcoding reliability commitment and confidence. Skip incomplete machines. Expired offers (past `end_date`) are skipped so a re-list run does not unpublish live SLA listings. **Before fleet SLA rollout:** @@ -387,26 +387,27 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do fi machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') - price=$(echo "$machine" | jq -r '.price_gpu // empty') + if ! echo "$machine" | jq -e '.listed == true' >/dev/null; then + echo "skip $id: not listed (this loop never republishes unlisted machines)"; continue + fi + price=$(echo "$machine" | jq -r '.listed_gpu_cost // empty') end=$(echo "$machine" | jq -r '.end_date // empty') - chunk=$(echo "$machine" | jq -r '.min_chunk // empty') + chunk=$(echo "$machine" | jq -r '.listed_min_gpu_count // empty') if [ -z "$price" ] || [ -z "$end" ] || [ -z "$chunk" ]; then - echo "skip $id: missing price_gpu/end_date/min_chunk"; continue + echo "skip $id: missing listed_gpu_cost/end_date/listed_min_gpu_count"; continue fi now=$(date -u +%s) if ! jq -e -n --argjson end "$end" --argjson now "$now" '$end > $now' >/dev/null 2>&1; then echo "skip machine_id=$id: end_date expired"; continue fi # Opt-in only: skip machines with no positive reliability commitment (do not invent 0.99) - if ! echo "$machine" | jq -e '(.sla_r_claim // 0) > 0' >/dev/null; then - echo "skip $id: no positive sla_r_claim (enable SLA per machine first)"; continue - fi - if ! echo "$machine" | jq -e '.sla_sigma_x != null' >/dev/null; then - echo "skip $id: sla_sigma_x missing in raw JSON (not SLA-ready; set Confidence / PUT sla_sigma_x, then re-run — do not assume 0.5)"; continue + if ! echo "$machine" | jq -e '(.sla_reliability_claim // 0) > 0' >/dev/null; then + echo "skip $id: no positive sla_reliability_claim (enable SLA per machine first)"; continue fi + # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. body=$(echo "$machine" | jq -c \ - '{machine: (.id|tonumber), price_gpu, end_date, min_chunk, - sla_r_claim, sla_sigma_x}') + '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, end_date, + min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim}') if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi @@ -508,7 +509,7 @@ When SLA is enabled on an offer, clients see: Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand). Match disk allocation before comparing `dph_total` across channels (CLI default is often 5 GiB; console Search is typically 10 GB; REST examples often use 8 GB `allocated_storage`): ```bash -vastai search offers 'machine_id=12345 verified=any has_sla=true target_reliability=0.95' --storage 10 --raw \ +vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw \ | jq '[.[] | select(.is_bid == false) | {id, num_gpus, dph_total, expected_reliability, reliability}]' ``` @@ -618,7 +619,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — Review reliability; re-run the backtester over the affected dates and check `escrow_to_client_balance` and `reliability` on those days. - **Severe outage (active SLA contracts):** - 1. Notify renters now: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS`. + 1. Notify renters now: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. 2. Stop new SLA rentals. The fastest way is `vastai unlist machine MACHINE_ID`, which publishes nothing. Alternatively, set the reliability commitment to `0` in **Set Pricing → SLA** (or API `sla_r_claim=0`), but only on machines that are currently listed, because `create_asks` publishes a live listing. 3. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 4. After the next UTC midnight, check `sla_earn` for the affected day. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 7d6d9d5e..e2aae1e5 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -5,7 +5,7 @@ Schedule an upcoming maintenance window ## Usage ```bash -vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY] +vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY ``` `schedule maintenance` is an alias for `schedule maint` if your CLI build supports both spellings. Prefer `maint`. Requires `machine_write` on scoped API keys — see [Permissions](/api-reference/permissions). @@ -28,8 +28,8 @@ vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_c Maintenance duration in hours. Prefer whole hours for REST compatibility (OpenAPI `duration` is an integer). The CLI may accept fractional values (for example `0.5`). - - (optional) can be one of [power, internet, disk, gpu, software, other] + + One of `power`, `internet`, `disk`, `gpu`, `software`, `other`. Always pass it: if you omit it, the CLI sends `"not provided"`, which the API rejects with HTTP 400. Use `other` when nothing else fits. From e644986950d2ca1c682d401b508da984a4d58ef2 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 16:50:29 -0700 Subject: [PATCH 145/250] docs(sla): fix r_claim ceiling and fleet backtest fallbacks (cycle 95) The listing and backtester accept sla_r_claim up to 0.99999 (MAX_R), not 0.9999. In the fleet backtest, R and P now only fill in for machines without SLA terms instead of overriding every machine's own values. Co-Authored-By: Claude Opus 5.5 (1M context) --- api-reference/openapi.yaml | 6 ++--- api-reference/openapi/yaml/list_machine.yaml | 4 ++-- host/sla-backtester.mdx | 24 +++++++++++--------- host/sla-offers.mdx | 4 ++-- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 2d063d2b..dfa26c42 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4593,12 +4593,12 @@ paths: type: number format: float minimum: 0 - maximum: 0.9999 + maximum: 0.99999 description: 'Host reliability claim. Values above 0 enable SLA on the offer. - Must be greater than 0 and at most 0.9999 when enabling SLA; exactly - 1.0 is rejected. + Must be greater than 0 and at most 0.99999 when enabling SLA; + exactly 1.0 is rejected. Set to 0 to disable SLA on new rentals. diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 59ebe5c2..797164a7 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -68,10 +68,10 @@ paths: type: number format: float minimum: 0 - maximum: 0.9999 + maximum: 0.99999 description: | Host reliability claim. Values above 0 enable SLA on the offer. - Must be greater than 0 and at most 0.9999 when enabling SLA; exactly 1.0 is rejected. + Must be greater than 0 and at most 0.99999 when enabling SLA; exactly 1.0 is rejected. Set to 0 to disable SLA on new rentals. sla_sigma_x: type: number diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 1c6c7e84..a65dd4fd 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -274,31 +274,33 @@ Optional, for API automation only. To check one machine, use the single-machine **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). -1. Run backtests **sequentially**, one machine at a time. The loop reads each machine's `sla_reliability_claim` and `sla_confidence` label from `show machines`. For machines that don't have SLA yet, set `R` (commitment) and `P` (confidence `p`) to backtest them before you enable SLA. Machines with neither are skipped and logged. The confidence label is a band, so a custom `sla_sigma_x` is backtested at the nearest band's `p`; set `P` to test an exact value. +1. Run backtests **sequentially**, one machine at a time. The loop reads each machine's `sla_reliability_claim` and `sla_confidence` label from `show machines`. For machines that don't have SLA yet, set `R` (commitment) and `P` (confidence `p`) to backtest them before you enable SLA. Machines with neither are skipped and logged. The confidence label is a band, so a custom `sla_sigma_x` is backtested at the nearest band's `p`; backtest that machine with the single-machine request to test an exact `p`. 2. Responses are written to a private temp directory that is deleted when the loop exits. ```bash export VAST_API_KEY="YOUR_API_KEY" -# Optional overrides for machines without SLA yet: R=0.99 P=0.6667 (Normal). +# Optional fallbacks for machines without SLA yet (machines with SLA keep their own terms): R=0.99 P=0.6667 BT_DIR=$(mktemp -d) trap 'rm -rf "$BT_DIR"' EXIT machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') - r="${R:-$(echo "$machine" | jq -r '.sla_reliability_claim // empty')}" + r=$(echo "$machine" | jq -r '.sla_reliability_claim // empty') + r="${r:-${R:-}}" # R only fills in for machines without SLA terms if ! jq -e -n --arg r "$r" 'try (($r | tonumber) > 0) catch false' >/dev/null 2>&1; then echo "skip $id: no sla_reliability_claim; set R=0.99 (or your planned commitment) to backtest before enabling SLA"; continue fi - p="${P:-}" + # show machines returns confidence as a label: high = Tight, medium = Normal, low = Wide. + # P only fills in for machines without SLA terms. + case "$(echo "$machine" | jq -r '.sla_confidence // empty')" in + high) p=0.83 ;; + medium) p=0.6667 ;; + low) p=0.50 ;; + *) p="${P:-}" ;; + esac if [ -z "$p" ]; then - # show machines returns confidence as a label: high = Tight, medium = Normal, low = Wide. - case "$(echo "$machine" | jq -r '.sla_confidence // empty')" in - high) p=0.83 ;; - medium) p=0.6667 ;; - low) p=0.50 ;; - *) echo "skip $id: no sla_confidence; set P=0.6667 (Normal) to backtest before enabling SLA"; continue ;; - esac + echo "skip $id: no sla_confidence; set P=0.6667 (Normal) to backtest before enabling SLA"; continue fi out="$BT_DIR/sla_bt_$id.json" http=$(curl -s -o "$out" -w "%{http_code}" \ diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 5928a443..ae63299d 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -145,7 +145,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | -| Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.9999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | +| Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.99999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | | Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA charges for clients at a given target). Defaults to `0.5` if omitted. | ### Advanced: `sla_max_beta` (optional) @@ -197,7 +197,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r Offers with invalid combinations are rejected at listing time: -- `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.9999**. Exactly `1.0` is rejected. +- `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.99999**. Exactly `1.0` is rejected. - When the reliability commitment is positive, `sla_sigma_x` must be positive and at most `3.0` (defaults to `0.5` if omitted). - Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. From 6dc799727392f8c50d7db07e03f4c1c5b0f5ae81 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 16:52:57 -0700 Subject: [PATCH 146/250] docs(sla): address doc-review consensus (cycle 96) Correct rent error codes, earnings identity, and the SLA Fee label so examples match the API. Co-authored-by: Cursor --- api-reference/openapi.yaml | 40 ++++++------------- .../openapi/yaml/create_instance.yaml | 10 ++--- api-reference/permissions.mdx | 2 +- cli/reference/create-instance.mdx | 2 +- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 23 +++++------ host/sla-offers.mdx | 28 +++++-------- sdk/python/reference/create-instance.mdx | 2 +- 8 files changed, 42 insertions(+), 67 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index dfa26c42..756de0e3 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1655,23 +1655,14 @@ paths: format: float minimum: 0 exclusiveMaximum: true - description: 'Client SLA coverage target (greater than 0 and less - than 1). When set on an SLA-enabled offer - - (`sla_r_claim > 0`), locks SLA terms on the new contract. Omit - or set to 0 for a non-SLA rental. - - Use the same value you used in search when comparing `dph_total`. - - Common failures: `invalid_args` when the offer has no SLA or the - target is out of range; - - `invalid_price` when the quote is stale relative to search (re-search - with matching storage - - and `target_reliability`, then rent again). See [SLA Coverage](/guides/instances/choosing/sla-coverage). - - ' + description: "Client SLA coverage target (greater than 0 and less\ + \ than 1). When set on an SLA-enabled offer\n(`sla_r_claim > 0`),\ + \ locks SLA terms on the new contract. Omit or set to 0 for a\ + \ non-SLA rental.\nUse the same value you used in search when\ + \ comparing `dph_total`.\nCommon failures: `invalid_sla_params`\ + \ when the offer has no SLA, the target is above the host commitment,\ + \ the target is out of range, or the SLA fee would exceed 1\xD7\ + \ compute.\nSee [SLA Coverage](/guides/instances/choosing/sla-coverage).\n" runtype: type: string description: 'Launch mode for the instance. If omitted, defaults @@ -1816,16 +1807,10 @@ paths: description: ID of the newly created instance contract example: 1234568 '400': - description: 'Bad Request. Includes invalid or out-of-range `target_reliability`, - renting with SLA on a non-SLA - - offer, SSH key requirements, and `invalid_price` when the create request - does not match a fresh - - search quote (re-search with the same `target_reliability` and disk/storage, - then retry). - - ' + description: "Bad Request. SLA failures use `invalid_sla_params` (no SLA\ + \ on the offer, target above the host commitment, target out of range,\ + \ or SLA fee above 1\xD7 compute). Also SSH key requirements and `no_such_ask`\ + \ when the offer is gone.\n" content: application/json: schema: @@ -1838,6 +1823,7 @@ paths: type: string enum: - invalid_args + - invalid_sla_params - invalid_price - no_ssh_key_for_vm msg: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 4bc462fe..ab41040b 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -78,9 +78,8 @@ paths: Client SLA coverage target (greater than 0 and less than 1). When set on an SLA-enabled offer (`sla_r_claim > 0`), locks SLA terms on the new contract. Omit or set to 0 for a non-SLA rental. Use the same value you used in search when comparing `dph_total`. - Common failures: `invalid_args` when the offer has no SLA or the target is out of range; - `invalid_price` when the quote is stale relative to search (re-search with matching storage - and `target_reliability`, then rent again). See [SLA Coverage](/guides/instances/choosing/sla-coverage). + Common failures: `invalid_sla_params` when the offer has no SLA, the target is above the host commitment, the target is out of range, or the SLA fee would exceed 1× compute. + See [SLA Coverage](/guides/instances/choosing/sla-coverage). runtype: type: string description: | @@ -200,9 +199,7 @@ paths: example: 1234568 '400': description: | - Bad Request. Includes invalid or out-of-range `target_reliability`, renting with SLA on a non-SLA - offer, SSH key requirements, and `invalid_price` when the create request does not match a fresh - search quote (re-search with the same `target_reliability` and disk/storage, then retry). + Bad Request. SLA failures use `invalid_sla_params` (no SLA on the offer, target above the host commitment, target out of range, or SLA fee above 1× compute). Also SSH key requirements and `no_such_ask` when the offer is gone. content: application/json: schema: @@ -215,6 +212,7 @@ paths: type: string enum: - invalid_args + - invalid_sla_params - invalid_price - no_ssh_key_for_vm msg: diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b9c342be..51a13f1a 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -166,7 +166,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings (console billing needs no API key; API earnings need `billing_read`). Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | | Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10` (`verified=any` is often required when checking your own machine). | -Earnings URLs look like `/api/v0/users/{user_id}/machine-earnings/`. Copy `{user_id}` from **Account → Profile**. If `vastai show user` is denied on this key, add `user_read`. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). +Earnings URL: `GET /api/v0/users/me/machine-earnings/`. The path user id is ignored; the API key owner is used, so do not add `user_read` just to discover an id. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). ## Custom Roles diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 58e0da1a..15d2e7af 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -11,7 +11,7 @@ Create a new instance **SLA** - This command cannot set `target_reliability`. -- No **SLA fee** / **SLA charge** line in the price breakdown means you do **not** have an SLA (even if search quoted SLA). +- No **SLA Fee** line in the price breakdown means you do **not** have an SLA (even if search quoted SLA). - Enable SLA in the console: **Search filters** (left bar) → **Reliability target**, confirm **SLA fee**, then **RENT**—or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. - See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). Match `--disk` to any `--storage` you used in search. diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 62428f88..d4907263 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA Fee** line in the price breakdown. An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -CLI and API search only **quote** SLA pricing—they do not turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA fee** / **SLA charge** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). +CLI and API search only **quote** SLA pricing—they do not turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA Fee** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 385e7875..8053f9e3 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -98,7 +98,7 @@ Bandwidth is billed separately from usage (`inet_*` rates) and is **not** includ | Host reliability commitment | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher commitment → lower SLA fee at a given reliability target | | Host confidence | Host-side pricing setting that affects SLA charge size. **You do not set this** — the host chooses it, and it is **not shown on offer cards**. Compare offers using `dph_total` or the SLA charge line in the price breakdown | -**Rule of thumb:** pick a reliability target **at or below** the host's reliability commitment for the best value. Asking for a 99% reliability target on a host whose reliability commitment is only 95% costs much more than asking for 95% on a host whose reliability commitment is 99%. In search results, the host reliability commitment appears as **expected reliability** on the offer (API: `expected_reliability`) — not the Reliability Score on the card. +**Rule of thumb:** your reliability target must be **at or below** the host's reliability commitment. Offers whose commitment is below your target are not shown in search and cannot be rented. At the same target, a host with a higher commitment charges a lower SLA fee. In search results, the host reliability commitment appears as **expected reliability** on the offer (API: `expected_reliability`) — not the Reliability Score on the card. ### Example: H100 at $3.50/hr GPU @@ -210,8 +210,6 @@ Web app: [cloud.vast.ai](https://cloud.vast.ai). REST examples use `https://cons For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). -Renters set **`target_reliability`** on search and on REST rent. Do not send **`sla_r_target`** or **`sla_r_claim`** in the rent body. - **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash @@ -288,16 +286,15 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Symptom | Typical response | What to do | | --- | --- | --- | -| Target on a non-SLA offer | HTTP 400 `invalid_args` | Search with `has_sla=true`; confirm `expected_reliability` | -| Target out of range / invalid | HTTP 400 `invalid_args` | Use `0 < target_reliability < 1`; stay at or below a realistic host reliability commitment | -| Offer not found or not available | HTTP 404 `invalid_args` (`msg` may include `no_such_ask`) | Do not retry that id; search again and rent a current offer | +| Offer has no SLA, target is above the host commitment, target is out of range, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | +| SLA not enabled for the account or region | HTTP 403 `sla_disabled` | Contact support | +| Offer no longer exists | HTTP 400 `invalid_args`, message `no_such_ask` | Re-search and use a fresh offer ID | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | -| Price mismatch after stale quote | HTTP 400 `invalid_price` | Re-search with the same `target_reliability` and storage (`allocated_storage` / `--storage`), then rent again | +| `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | Before sending the same `PUT` again, check `GET /api/v1/instances/` for a new contract. There is no idempotency key, so a blind retry can create a second paid rental. | | Too many requests | HTTP 429 | Wait and back off. Before retrying the same `PUT`, confirm with `GET /api/v1/instances/` whether the contract already exists. If retry returns `invalid_price`, `no_such_ask`, 404, or 410, re-search with the same `target_reliability` and storage, then rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | -| Forbidden / wrong account | HTTP 403 | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | -| SLA with a bid or interruptible offer | Rent does not turn on an SLA | Search with `"type": "ondemand"`. Do not send `price` or `bid_price` when you want an SLA. | +| Forbidden / wrong account | HTTP 400 `invalid_args` from a host account | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | | Channel | Default storage | Field | Units (label) | | --- | --- | --- | --- | @@ -338,7 +335,7 @@ Each day, the platform tracks how long your instance was online. Settlement cons - A pattern of unreliable uptime produces larger credits over time. - One strong day after a weak week does not instantly reset everything. -Scheduled maintenance with adequate advance notice (typically 24+ hours) may be credited toward reliability on a case-by-case basis. Check **Instances** status and any client notifications during downtime to distinguish planned maintenance from an unexpected outage. Credited maintenance is not a separate field on instance webhooks or `GET /api/v0/charges/`. Unplanned outages count fully. +When a host schedules maintenance in advance, part of that downtime is counted as uptime for the host. More of the window is forgiven the earlier they give notice, and less is forgiven the longer the window lasts. Forgiven downtime does not earn you a service credit. Check **Instances** status and any notifications to distinguish planned maintenance from an unexpected outage. Unplanned outages count fully. ### Credit scenarios (simplified) @@ -346,11 +343,11 @@ Using the H100 example ($84/day compute, ~$0.20/day SLA charge, target 95%, host | Scenario | Approx. SLA charge | Approx. service credit | Net vs no SLA (approx.) | | --- | --- | --- | --- | -| Above target (excellent / good day) | ~$0.20/day | $0 (often) | **−$0.20** (you paid the SLA charge) | -| Near / below target on blended measure (~95%) | ~$0.20/day | ~$42 | **+$41.80** (net credit after SLA charge) | +| Above target (excellent / good day) | ~$0.20/day | $0 | **−$0.20** (you paid the SLA fee) | +| Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (net credit after SLA fee) | | Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | -**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without the SLA. +**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without the SLA. Credits are graduated. A day close to your target can pay a small credit, and the further below target the day falls, the larger the credit. A day that meets the target does not pay a credit. Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index ae63299d..74f8f08d 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -113,7 +113,7 @@ Think of an SLA offer as two host ideas plus one client choice: 1. **Your reliability commitment** — what you believe your machine will deliver (`sla_r_claim`). Setting this above `0` enables SLA on the offer. 2. **Your confidence** — how wide your belief is around that reliability commitment (`sla_sigma_x`). Tighter confidence → lower SLA charges for clients at a given target; wider confidence → higher charges. -3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA charge sizing use this target. Clients typically pick a target **at or below** your reliability commitment. +3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA fee sizing use this target. A renter's target must be **at or below** your reliability commitment. Search hides offers whose commitment is below the target, and rent rejects that combination. When a client rents an on-demand instance on your SLA-listed offer with a chosen target: @@ -325,7 +325,7 @@ Omitted non-SLA fields retain their current listing values; only fields present vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, listed, sla_reliability_claim, sla_confidence, listed_gpu_cost, listed_min_gpu_count, end_date}' ``` -REST equivalent: `GET /api/v0/machines/?user_id={user_id}` (`user_id` is required). Get `user_id` from **Account → Profile** or `vastai show user`. The CLI supplies `user_id` for you. +REST equivalent: `GET /api/v0/machines/` (the CLI sends `?owner=me`). The account is the API key owner; a `?user_id=` query is ignored. Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence` (`high` = Tight, `medium` = Normal, `low` = Wide), not as `sla_sigma_x`. The SLA fields are `null` unless the machine is listed with SLA terms. Pricing fields and `end_date` are `null` when the machine is not listed. @@ -405,9 +405,10 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: no positive sla_reliability_claim (enable SLA per machine first)"; continue fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. + # price_disk is sent: omitting it resets storage price to 0.10. body=$(echo "$machine" | jq -c \ - '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, end_date, - min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim}') + '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, + end_date, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim}') if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi @@ -583,7 +584,7 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **Or use CLI/REST below.** A service credit is not guaranteed either way. -**Planned SLA maintenance (renters may qualify for a service credit — not guaranteed):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate` and `--duration`. Advance notice (not the category value) is what makes maintenance “planned” for service-credit review. Valid `--maintenance_category` values: `power`, `internet`, `disk`, `gpu`, `software`, `other`. Renters should check **Instances** for status. Credited maintenance is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. Credit eligibility is evaluated on a case-by-case basis. +**Planned SLA maintenance (renters may qualify for a service credit — not guaranteed):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Advance notice (not the category value) is what maintenance forgiveness uses. Scheduling earlier counts more of the window as uptime; a longer window counts less. Rescheduling resets the notice clock. Forgiven downtime is not a cash credit to the renter. Renters should check **Instances** for status. It is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. **`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -685,9 +686,9 @@ Positive `sla_earn` = net SLA charge you kept that period; negative = net credit | List or update SLA on an offer | `machine_write` | | Post-listing SLA earnings | `billing_read` | -`GET /api/v0/users/{user_id}/machine-earnings/` returns SLA fields alongside compute earnings. Requires a **`billing_read`** API key. See [`show earnings`](/api-reference/billing/show-earnings). +`GET /api/v0/users/me/machine-earnings/` returns SLA fields alongside compute earnings. The path user id is ignored; the account is the API key owner, so a **`billing_read`** key is enough (you do not need `user_read`). See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited. Poll `GET /api/v0/users/{user_id}/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, one pull with `last_days=1` after UTC rollover is usually enough. +This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, one pull with `last_days=1` after UTC rollover is usually enough. **Automation pattern:** There is no host webhook for SLA settlement. Poll `machine-earnings` with `last_days=1` and `machid`, alert on `per_machine[].sla_earn` thresholds, and call machines sequentially with backoff on 429. Do not use `per_day[].sla_earn` for a single machine. @@ -699,23 +700,17 @@ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA sett - **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window. -Replace `{user_id}` with your account ID from **Account → Profile** (preferred for `billing_read`-only keys). Optional CLI: `USER_ID=$(vastai show user --raw | jq -r '.id')` — that needs `user_read` if `show user` is denied; see [Host SLA scoped-key recipe](/api-reference/permissions#host-sla-scoped-key-recipe). - -```bash -USER_ID=YOUR_USER_ID # from Account → Profile -``` - ```bash # Exact UTC day 2026-07-24 for machine 12345 (sday/eday = 20658) curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/users/${USER_ID}/machine-earnings/?machid=12345&sday=20658&eday=20658" \ + "https://console.vast.ai/api/v0/users/me/machine-earnings/?machid=12345&sday=20658&eday=20658" \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` ```bash # Fleet snapshot (last_days=1 — coarse, not a settled calendar day) curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/users/${USER_ID}/machine-earnings/?last_days=1" \ + "https://console.vast.ai/api/v0/users/me/machine-earnings/?last_days=1" \ | jq '.per_machine[] | {machine_id, sla_earn}' ``` @@ -723,7 +718,7 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ ```bash curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/users/${USER_ID}/machine-earnings/?machid=12345&last_days=1" \ + "https://console.vast.ai/api/v0/users/me/machine-earnings/?machid=12345&last_days=1" \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` @@ -736,7 +731,6 @@ Do **not** compare `last_days=7` totals to the backtester's largest single-day c | `per_machine[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | | Fleet `per_day[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | -- `{user_id}` — Use your account ID from **Account → Profile** (recommended). Use `vastai show user` only if your API key includes `user_read`; `billing_read`-only keys cannot call it. Do not leave a curly-brace placeholder in the URL. - Settlement is evaluated on UTC day boundaries. Rows typically update within a few hours after UTC midnight. ## Tips for competitive SLA offers diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 888741aa..34ccae4f 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create_instance" Create a new instance from an offer/ask ID returned by search. -**SLA:** `target_reliability` is not available on `create_instance()` today. If the instance price breakdown has no **SLA fee** / **SLA charge** line, you do **not** have an SLA—even if search showed SLA pricing. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). +**SLA:** `target_reliability` is not available on `create_instance()` today. If the instance price breakdown has no **SLA Fee** line, you do **not** have an SLA—even if search showed SLA pricing. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). ## Signature From 1305bd27fa19ad09769223e0f3c7c99006946552 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:01:40 -0700 Subject: [PATCH 147/250] docs(sla): address doc-review consensus (cycle 97) Stop partial create_asks examples from resetting storage price, duration, and visibility, and describe sla_earn as escrow released to the host. Co-authored-by: Cursor --- api-reference/openapi.yaml | 69 ++++++++++++++----- api-reference/openapi/yaml/list_machine.yaml | 2 +- api-reference/openapi/yaml/show_earnings.yaml | 4 +- api-reference/openapi/yaml/show_machines.yaml | 24 ++++++- cli/reference/show-earnings.mdx | 2 +- host/sla-offers.mdx | 62 +++++++++-------- 6 files changed, 113 insertions(+), 50 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 756de0e3..fcb497fb 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4518,10 +4518,11 @@ paths: summary: list machine description: "Creates or updates ask contracts for a machine to list it for\ \ rent on the vast.ai platform.\nAllows setting offer pricing, rental types,\ - \ end dates, discount rates, and SLA parameters.\nUnspecified fields keep\ - \ their current listing values (partial update). For an SLA-only change, send\ - \ the machine id plus SLA fields. Read the current offer with show machines\ - \ before changing pricing or the end date.\n\nSLA request-body fields (`sla_r_claim`,\ + \ end dates, discount rates, and SLA parameters.\nUnspecified fields generally\ + \ keep their current values, except `price_disk` (defaults to 0.10), `duration`\ + \ (cleared if omitted) and `hidden_listing` (defaults to false). Send those\ + \ explicitly on every update. Read the current offer with show machines before\ + \ changing pricing or the end date.\n\nSLA request-body fields (`sla_r_claim`,\ \ `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint.\ \ SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy\ \ `sla_reliability` are ignored \u2014 clients choose a reliability target\ @@ -8006,8 +8007,11 @@ paths: type: number sla_earn: type: number - description: Net SLA earnings for this machine over the - window. + description: Escrow released to the host for this machine + over the window (net compute plus SLA fee, minus service + credits). SLA-contract compute is not included in gpu_earn + or sto_earn. Normally positive; negative only when a prior + day is corrected. per_day: type: array items: @@ -8025,9 +8029,9 @@ paths: type: number sla_earn: type: number - description: Net host SLA settlement for the UTC day. Positive - when the host keeps the SLA charge; negative when the - host credits the client. + description: Fleet-wide escrow released to the host that + UTC day (same meaning as per_machine sla_earn). Not fees-minus-credits, + and not a per-machine figure. '400': description: Bad Request - Invalid input syntax content: @@ -8940,17 +8944,23 @@ paths: /api/v0/machines: get: summary: show machines - description: "Fetches data for multiple machines associated with the authenticated\ - \ user.\n\nThe `--raw` CLI output includes listing and SLA fields (`price_gpu`,\ - \ `end_date`, `sla_r_claim`, `sla_sigma_x`, etc.) used for read-modify-write\ - \ before partial SLA updates. See [SLA Offers \u2014 Partial updates](/host/sla-offers#api-for-automation).\n\ - \nCLI Usage: `vastai show machines [--user_id ]`" + description: 'Fetches data for multiple machines associated with the authenticated + user. + + + `--raw` includes listing state for read-modify-write: `listed`, `listed_gpu_cost` + (send as `price_gpu`), `listed_storage_cost` (send as `price_disk`), `end_date`, + `duration`, `sla_reliability_claim` (send as `sla_r_claim`) and the `sla_confidence` + band label. `sla_sigma_x` is not returned. See [SLA Offers](/host/sla-offers#api-for-automation). + + + CLI Usage: `vastai show machines [--user_id ]`' operationId: getMachines parameters: - name: user_id in: query - required: true - description: The ID of the user whose machines are being requested. + required: false + description: Ignored. Results are scoped to the API key owner. schema: type: string responses: @@ -8982,6 +8992,31 @@ paths: - 'null' description: Listed GPU price in $/hour (`price_gpu` on create_asks). null when not listed. + listed_storage_cost: + type: + - number + - 'null' + description: Listed storage price in $/GB/month (`price_disk` + on create_asks). null when not listed. Omitting `price_disk` + on update resets it to 0.10. + listed_inet_up_cost: + type: + - number + - 'null' + description: Listed upload bandwidth price (`price_inetu` + on create_asks). + listed_inet_down_cost: + type: + - number + - 'null' + description: Listed download bandwidth price (`price_inetd` + on create_asks). + duration: + type: + - number + - 'null' + description: Auto-renew duration. Send it back on create_asks + or the listing stops auto-renewing. end_date: type: - number @@ -9026,6 +9061,8 @@ paths: name: my-h100 listed: true listed_gpu_cost: 3.5 + listed_storage_cost: 0.15 + duration: null end_date: 1735689600 listed_min_gpu_count: 1 sla_reliability_claim: 0.99 diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 797164a7..d443a566 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -13,7 +13,7 @@ paths: description: | Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. - Unspecified fields keep their current listing values (partial update). For an SLA-only change, send the machine id plus SLA fields. Read the current offer with show machines before changing pricing or the end date. + Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted) and `hidden_listing` (defaults to false). Send those explicitly on every update. Read the current offer with show machines before changing pricing or the end date. SLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are ignored — clients choose a reliability target at search/rent time. The published CLI and SDK do not yet expose SLA fields — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 2bee32a4..e164a391 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -118,7 +118,7 @@ paths: type: number sla_earn: type: number - description: Net SLA earnings for this machine over the window. + description: Escrow released to the host for this machine over the window (net compute plus SLA fee, minus service credits). SLA-contract compute is not included in gpu_earn or sto_earn. Normally positive; negative only when a prior day is corrected. per_day: type: array items: @@ -136,7 +136,7 @@ paths: type: number sla_earn: type: number - description: Net host SLA settlement for the UTC day. Positive when the host keeps the SLA charge; negative when the host credits the client. + description: Fleet-wide escrow released to the host that UTC day (same meaning as per_machine sla_earn). Not fees-minus-credits, and not a per-machine figure. '400': description: Bad Request - Invalid input syntax content: diff --git a/api-reference/openapi/yaml/show_machines.yaml b/api-reference/openapi/yaml/show_machines.yaml index 91a3cb91..54642d99 100644 --- a/api-reference/openapi/yaml/show_machines.yaml +++ b/api-reference/openapi/yaml/show_machines.yaml @@ -9,15 +9,15 @@ paths: description: | Fetches data for multiple machines associated with the authenticated user. - The `--raw` CLI output includes listing and SLA fields (`price_gpu`, `end_date`, `sla_r_claim`, `sla_sigma_x`, etc.) used for read-modify-write before partial SLA updates. See [SLA Offers — Partial updates](/host/sla-offers#api-for-automation). + `--raw` includes listing state for read-modify-write: `listed`, `listed_gpu_cost` (send as `price_gpu`), `listed_storage_cost` (send as `price_disk`), `end_date`, `duration`, `sla_reliability_claim` (send as `sla_r_claim`) and the `sla_confidence` band label. `sla_sigma_x` is not returned. See [SLA Offers](/host/sla-offers#api-for-automation). CLI Usage: `vastai show machines [--user_id ]` operationId: getMachines parameters: - name: user_id in: query - required: true - description: The ID of the user whose machines are being requested. + required: false + description: Ignored. Results are scoped to the API key owner. schema: type: string responses: @@ -46,6 +46,22 @@ paths: type: number nullable: true description: Listed GPU price in $/hour (`price_gpu` on create_asks). null when not listed. + listed_storage_cost: + type: number + nullable: true + description: Listed storage price in $/GB/month (`price_disk` on create_asks). null when not listed. Omitting `price_disk` on update resets it to 0.10. + listed_inet_up_cost: + type: number + nullable: true + description: Listed upload bandwidth price (`price_inetu` on create_asks). + listed_inet_down_cost: + type: number + nullable: true + description: Listed download bandwidth price (`price_inetd` on create_asks). + duration: + type: number + nullable: true + description: Auto-renew duration. Send it back on create_asks or the listing stops auto-renewing. end_date: type: number nullable: true @@ -73,6 +89,8 @@ paths: name: my-h100 listed: true listed_gpu_cost: 3.5 + listed_storage_cost: 0.15 + duration: null end_date: 1735689600 listed_min_gpu_count: 1 sla_reliability_claim: 0.99 diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index a13cfbc1..f84a1b09 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -6,7 +6,7 @@ sidebarTitle: "show earnings" Get machine earnings history reports. -Host settlement command. `sla_earn` is host SLA settlement, not renter credits. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [Where do I see historical SLA credits?](/guides/instances/choosing/sla-coverage#where-do-i-see-historical-sla-credits). +Host settlement command. For SLA contracts, `sla_earn` is the escrow released to the host that day (net compute plus the SLA fee, minus service credits), not a credit balance and not renter credits. SLA-contract compute is omitted from `gpu_earn`. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [Where do I see historical SLA credits?](/guides/instances/choosing/sla-coverage#where-do-i-see-historical-sla-credits). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 74f8f08d..f1d2ddae 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -276,10 +276,10 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": 0.15, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Do not copy example `price_gpu` or `end_date` from docs into a first listing—read current values from `vastai show machines --raw`. +Replace `price_disk` with the machine's current `listed_storage_cost` from `vastai show machines --raw`. Omitting it resets storage to **$0.10/GB/month**. Do not copy example prices or `end_date` into a first listing. #### Full listing update (existing ask) @@ -292,6 +292,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{ "machine": 12345, "price_gpu": 3.50, + "price_disk": 0.15, "sla_r_claim": 0.99, "sla_sigma_x": 0.5, "end_date": 1893456000 @@ -308,6 +309,7 @@ SLA fields example (existing listing, same limit as the curl above): { "machine": 12345, "price_gpu": 3.50, + "price_disk": 0.15, "end_date": 1893456000, "sla_r_claim": 0.99, "sla_sigma_x": 0.5 @@ -316,13 +318,21 @@ SLA fields example (existing listing, same limit as the curl above): This creates an offer with a reliability commitment of `0.99` and confidence spread `0.5`. Clients who search with `target_reliability` below your reliability commitment see a lower SLA fee than clients who choose a reliability target near your reliability commitment. - -Partial updates are supported when editing an existing listing. If you change only one SLA field, the platform re-validates the merged parameters. Set `sla_r_claim` to `0` to disable SLA on an existing listing. + +`create_asks` is not a pure partial update. If you change only SLA fields, the platform re-validates the merged SLA parameters. Set `sla_r_claim` to `0` to disable SLA on an existing listing. Other omitted fields are not all kept: + +- `price_gpu` is kept if omitted. +- `price_disk` resets to **$0.10/GB/month** if omitted or `null`. +- `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing). +- `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. + +Always read the current listing and send `price_disk` and `duration` back. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`, `end_date` → `end_date`, `duration` → `duration`. + -Omitted non-SLA fields retain their current listing values; only fields present in the request body are updated. Read current listing fields from `vastai show machines --raw`: +Read current listing fields from `vastai show machines --raw`: ```bash -vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, listed, sla_reliability_claim, sla_confidence, listed_gpu_cost, listed_min_gpu_count, end_date}' +vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, listed, sla_reliability_claim, sla_confidence, listed_gpu_cost, listed_storage_cost, listed_min_gpu_count, end_date, duration}' ``` REST equivalent: `GET /api/v0/machines/` (the CLI sends `?owner=me`). The account is the API key owner; a `?user_id=` query is ignored. @@ -330,7 +340,6 @@ REST equivalent: `GET /api/v0/machines/` (the CLI sends `?owner=me`). The accoun Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence` (`high` = Tight, `medium` = Normal, `low` = Wide), not as `sla_sigma_x`. The SLA fields are `null` unless the machine is listed with SLA terms. Pricing fields and `end_date` are `null` when the machine is not listed. Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge → PUT). `vastai list machine` and the Python SDK listing helpers cannot set SLA fields; start from this REST pattern (or the console) when you move an existing CLI listing to SLA. - ### Fleet SLA re-list (machines that already have an SLA) @@ -393,8 +402,9 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do price=$(echo "$machine" | jq -r '.listed_gpu_cost // empty') end=$(echo "$machine" | jq -r '.end_date // empty') chunk=$(echo "$machine" | jq -r '.listed_min_gpu_count // empty') - if [ -z "$price" ] || [ -z "$end" ] || [ -z "$chunk" ]; then - echo "skip $id: missing listed_gpu_cost/end_date/listed_min_gpu_count"; continue + disk=$(echo "$machine" | jq -r '.listed_storage_cost // empty') + if [ -z "$price" ] || [ -z "$end" ] || [ -z "$chunk" ] || [ -z "$disk" ]; then + echo "skip $id: missing listed_gpu_cost/end_date/listed_min_gpu_count/listed_storage_cost"; continue fi now=$(date -u +%s) if ! jq -e -n --argjson end "$end" --argjson now "$now" '$end > $now' >/dev/null 2>&1; then @@ -405,10 +415,12 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: no positive sla_reliability_claim (enable SLA per machine first)"; continue fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. - # price_disk is sent: omitting it resets storage price to 0.10. + # price_disk is required: null or omitted resets storage price to 0.10. + # duration is sent when set so an auto-renew listing is not cleared. body=$(echo "$machine" | jq -c \ '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, - end_date, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim}') + end_date, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim} + + (if .duration == null then {} else {duration} end)') if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi @@ -431,13 +443,13 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid -**SLA-only update (existing ask only)** — include `machine` plus SLA fields; omit unrelated offer fields you intend to keep. Do **not** use this body for a first listing. +**SLA-only update (existing ask only)** — include `machine`, the current `price_disk`, and the SLA fields. Do **not** use this body for a first listing. Replace `0.15` with `listed_storage_cost`. ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' + -d '{"machine": 12345, "price_disk": 0.15, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` **Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. @@ -452,6 +464,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ | 403 | `sla_daemon_outdated` | Machine daemon build is too old for SLA listing | | 400 | `invalid_args` | Machine ID not found for your account, or malformed / incompatible request body | | 400 | `invalid_sla_params` | SLA parameters failed validation | +| 402 | `msg`: `can only create asks for an online machine` | The daemon has not checked in for more than 60 seconds. Wait until **Host → Machines** shows the machine online, then retry. If the machine is down, use `vastai unlist machine MACHINE_ID` instead. | **`machine_locked`:** Returned when a machine is decommissioned or migration-locked. If you are migrating hardware, finish or cancel active rentals first, remove or update the listing as needed, and contact support if the machine remains locked. Existing SLA terms on active contracts remain in force until those contracts end. @@ -621,7 +634,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **Unexpected credit** — Review reliability; re-run the backtester over the affected dates and check `escrow_to_client_balance` and `reliability` on those days. - **Severe outage (active SLA contracts):** 1. Notify renters now: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. - 2. Stop new SLA rentals. The fastest way is `vastai unlist machine MACHINE_ID`, which publishes nothing. Alternatively, set the reliability commitment to `0` in **Set Pricing → SLA** (or API `sla_r_claim=0`), but only on machines that are currently listed, because `create_asks` publishes a live listing. + 2. Stop new SLA rentals. The fastest way is `vastai unlist machine MACHINE_ID`, which publishes nothing. Setting the reliability commitment to `0` (`sla_r_claim=0`) only works while the machine is online. If it is down, `create_asks` returns HTTP 402 and `vastai unlist machine` is the path that works. Only change the commitment on machines that are currently listed, because `create_asks` publishes a live listing. Include the current `price_disk` on that update. 3. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 4. After the next UTC midnight, check `sla_earn` for the affected day. 5. Contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. @@ -630,20 +643,22 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). -When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. Do not compare `per_day` totals to one machine’s backtester largest single-day credit. +For SLA contracts, `sla_earn` is the escrow released to you that day: your net compute earnings plus the SLA fee, minus any service credits paid to the renter. It matches the backtester's `escrow_to_host_balance`. SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not treat a smaller `sla_earn` as a negative credit, and do not compare it to the backtester's largest single-day credit. + +When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. ### Console (recommended for day-to-day checks) 1. Go to **Host → Billing** (or **Earnings** / **Reports**). 2. Set the date range to include the UTC day you want to review. 3. Filter by machine ID if available. -4. Look for **SLA** entries in the earnings breakdown — positive amounts are SLA charges you kept; negative amounts are credits you owed the client. -5. After downtime, compare the affected UTC day(s) to your backtester largest single-day credit. +4. Look for the SLA settlement in the earnings breakdown. On an SLA rental, compute pay is released with the SLA fee (the same amount as `sla_earn` in the API), not as a separate GPU earnings line. +5. After downtime, a smaller release than a normal day can mean a service credit was paid. Do not look for a negative SLA line, and do not match that amount to the backtester's largest single-day credit. **If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). -SLA daily settlement (SLA charge kept / credit owed) does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. +SLA settlement does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. ### CLI @@ -670,7 +685,7 @@ vastai show earnings --machine_id 12345 --start_date "$(date -u -d 'yesterday' + | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' ``` -Positive `sla_earn` = net SLA charge you kept that period; negative = net credit you owe. Weekly aggregates are window totals, not daily series — use a one-day range above for day-level checks. +Weekly aggregates are window totals, not daily series — use a one-day range above for day-level checks. ### API (automation) @@ -690,7 +705,7 @@ Positive `sla_earn` = net SLA charge you kept that period; negative = net credit This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, one pull with `last_days=1` after UTC rollover is usually enough. -**Automation pattern:** There is no host webhook for SLA settlement. Poll `machine-earnings` with `last_days=1` and `machid`, alert on `per_machine[].sla_earn` thresholds, and call machines sequentially with backoff on 429. Do not use `per_day[].sla_earn` for a single machine. +**Automation pattern:** There is no host webhook for SLA settlement. Poll `machine-earnings` and read `per_machine[].sla_earn` (the escrow released that day, not a credit balance). Call machines sequentially with backoff on 429. Do not use `per_day[].sla_earn` for a single machine. When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. @@ -724,13 +739,6 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ Do **not** compare `last_days=7` totals to the backtester's largest single-day credit. -**Sign convention:** - -| Field | Strong day (meet client target) | Weak day (miss client target) | -| --- | --- | --- | -| `per_machine[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | -| Fleet `per_day[].sla_earn` | Positive (SLA charge kept) | Negative (credit you owe) | - - Settlement is evaluated on UTC day boundaries. Rows typically update within a few hours after UTC midnight. ## Tips for competitive SLA offers From 43cc38e0cdd1d578913a9f1d2fef339599b1cdb3 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:10:38 -0700 Subject: [PATCH 148/250] docs(sla): address doc-review consensus (cycle 98) Keep fleet re-lists from unhiding listings or sending duration with end_date, and stop calling maintenance forgiveness a service credit. Co-authored-by: Cursor --- api-reference/openapi.yaml | 36 +++++++++----- api-reference/openapi/yaml/list_machine.yaml | 11 ++++- host/hosting-overview.mdx | 4 +- host/sla-offers.mdx | 52 +++++++++++++------- snippets/host/cli/schedule-maint.mdx | 6 +-- snippets/host/sdk/list-machine.mdx | 2 +- 6 files changed, 73 insertions(+), 38 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index fcb497fb..d33485f4 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4520,16 +4520,17 @@ paths: \ rent on the vast.ai platform.\nAllows setting offer pricing, rental types,\ \ end dates, discount rates, and SLA parameters.\nUnspecified fields generally\ \ keep their current values, except `price_disk` (defaults to 0.10), `duration`\ - \ (cleared if omitted) and `hidden_listing` (defaults to false). Send those\ - \ explicitly on every update. Read the current offer with show machines before\ - \ changing pricing or the end date.\n\nSLA request-body fields (`sla_r_claim`,\ - \ `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint.\ - \ SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy\ - \ `sla_reliability` are ignored \u2014 clients choose a reliability target\ - \ at search/rent time. The published CLI and SDK do not yet expose SLA fields\ - \ \u2014 use the host console (**Set Pricing \u2192 SLA**) or REST/`curl`\ - \ until CLI/SDK support ships.\n\nCLI Usage (non-SLA fields): `vastai list\ - \ machine [options]`" + \ (cleared if omitted) and `hidden_listing` (defaults to false). Send `price_disk`\ + \ and `hidden_listing` on every update. Send either `duration` or `end_date`,\ + \ never both (400). Read the current offer with show machines before changing\ + \ pricing.\n\nSLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional\ + \ `sla_max_beta`) are supported on this REST endpoint. SLA activates when\ + \ `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are\ + \ ignored \u2014 clients choose a reliability target at search/rent time.\ + \ The published CLI and SDK do not yet expose SLA fields \u2014 use the host\ + \ console (**Set Pricing \u2192 SLA**) or REST/`curl` until CLI/SDK support\ + \ ships.\n\nCLI Usage (non-SLA fields): `vastai list machine \ + \ [options]`" security: - BearerAuth: [] requestBody: @@ -4571,7 +4572,20 @@ paths: end_date: type: number format: float - description: Unix timestamp for when the listing expires + description: Unix timestamp for when the listing expires. Do not + send together with `duration` (400 Cannot set both duration and + end_date). + duration: + type: number + format: float + description: Auto-renew length in seconds. Send this instead of + `end_date` for listings created with `vastai list machine -l`. + Omitting it on an auto-renew listing turns auto-renew off. + hidden_listing: + type: boolean + description: When true, the offer is not shown in search. Defaults + to false if omitted, which makes a hidden listing public. `show + machines` does not return this flag. credit_discount_max: type: number format: float diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index d443a566..4426abe6 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -13,7 +13,7 @@ paths: description: | Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. - Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted) and `hidden_listing` (defaults to false). Send those explicitly on every update. Read the current offer with show machines before changing pricing or the end date. + Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted) and `hidden_listing` (defaults to false). Send `price_disk` and `hidden_listing` on every update. Send either `duration` or `end_date`, never both (400). Read the current offer with show machines before changing pricing. SLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are ignored — clients choose a reliability target at search/rent time. The published CLI and SDK do not yet expose SLA fields — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. @@ -59,7 +59,14 @@ paths: end_date: type: number format: float - description: Unix timestamp for when the listing expires + description: Unix timestamp for when the listing expires. Do not send together with `duration` (400 Cannot set both duration and end_date). + duration: + type: number + format: float + description: Auto-renew length in seconds. Send this instead of `end_date` for listings created with `vastai list machine -l`. Omitting it on an auto-renew listing turns auto-renew off. + hidden_listing: + type: boolean + description: When true, the offer is not shown in search. Defaults to false if omitted, which makes a hidden listing public. `show machines` does not return this flag. credit_discount_max: type: number format: float diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 9574f365..f71292db 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -257,7 +257,7 @@ Use these paths in order: 2. **Planned downtime with active renters:** Schedule at least 24 hours ahead from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). 3. **Emergency or unplanned downtime:** Notify renters immediately with [`vastai schedule maint`](/host/cli/schedule-maint). -For SLA service-credit rules, notice windows, and confirmation steps, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). A service credit is not guaranteed. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. +For SLA maintenance-forgiveness rules, notice windows, and confirmation steps, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Forgiveness is not guaranteed, and it is not a payment to the host. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. ## Uninstalling @@ -306,7 +306,7 @@ No, there is not an established process for hosts to message clients on Vast. A drop in reliability does not by itself cost you your verification. What does is an active error. A machine stays de-verified while it has one, and is verified again once the error clears. -Restarting during an active rental does cost you reliability. Schedule a maintenance window first to keep the penalty smaller and recover sooner. That advice is about your marketplace reliability score. For SLA settlement, follow [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). A service credit is not guaranteed. +Restarting during an active rental does cost you reliability. Schedule a maintenance window first to keep the penalty smaller and recover sooner. That advice is about your marketplace reliability score. For SLA settlement, follow [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Maintenance forgiveness is not guaranteed. See [Understanding Verification](/host/understanding-verification). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f1d2ddae..29c0fe13 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -51,7 +51,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## Before you enable SLA -If you expect downtime during active rentals, notify renters before you take the machine down. Use either the console ([Set a maintenance window](/host/set-maintenance-window)) or the CLI/REST ([`vastai schedule maint`](/host/cli/schedule-maint)). Use one path per window. For SLA service-credit review, follow [Scheduled maintenance](#scheduled-maintenance): at least 24 hours' notice. A service credit is not guaranteed. +If you expect downtime during active rentals, notify renters before you take the machine down. Use either the console ([Set a maintenance window](/host/set-maintenance-window)) or the CLI/REST ([`vastai schedule maint`](/host/cli/schedule-maint)). Use one path per window. For maintenance forgiveness, follow [Scheduled maintenance](#scheduled-maintenance): at least 24 hours' notice. Forgiveness is not guaranteed, and it is not a service credit paid to you. **Pre-flight checklist (before tuning reliability commitment and confidence):** @@ -131,7 +131,7 @@ SLA reliability is measured at the **rental contract (instance) level** using pl - **Instance fails to start** when a client rents → counts against SLA reliability for that contract. - **Machine-level outage** while contracts are active → affects settlement for those contracts. - **Brief host reboots** during active rentals may count as downtime. Vast does not publish a fixed second-level threshold in host docs — treat unplanned reboots as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance) with at least 24 hours' notice when possible. -- **Scheduled maintenance** may receive credit case by case — see [Scheduled maintenance](#scheduled-maintenance). +- **Scheduled maintenance** may be partly forgiven (counted as uptime) — see [Scheduled maintenance](#scheduled-maintenance). That is not a service credit. On sliced machines, SLA settles **per rental contract**. If one GPU slice fails but others remain healthy, only contracts on the affected slice are measured for downtime. @@ -279,7 +279,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{"machine": 12345, "price_disk": 0.15, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `price_disk` with the machine's current `listed_storage_cost` from `vastai show machines --raw`. Omitting it resets storage to **$0.10/GB/month**. Do not copy example prices or `end_date` into a first listing. +Replace `price_disk` with the machine's current `listed_storage_cost` from `vastai show machines --raw`. Also send `duration` if the listing auto-renews, otherwise `end_date`, and `"hidden_listing": true` if it is hidden. See the read → merge → PUT warning below. Do not copy example prices into a first listing. #### Full listing update (existing ask) @@ -325,8 +325,9 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - `price_disk` resets to **$0.10/GB/month** if omitted or `null`. - `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing). - `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. +- Send **either** `duration` (when `show machines` returns a non-null `duration`) **or** `end_date`, never both. Both together returns `400` `Cannot set both duration and end_date`. -Always read the current listing and send `price_disk` and `duration` back. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`, `end_date` → `end_date`, `duration` → `duration`. +Always read the current listing and send `price_disk` plus either `duration` or `end_date`. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. Read current listing fields from `vastai show machines --raw`: @@ -367,6 +368,7 @@ Validate the listed price (`listed_gpu_cost`), `end_date`, and minimum GPU count 1. Update host daemons fleet-wide per the [host setup guide](https://cloud.vast.ai/host/setup/). 2. On **Host → Machines**, confirm each machine is healthy (no red error status) and retry **LIST** / `create_asks` after the daemon reconnects. 3. If listing still returns `sla_daemon_outdated` after an update, contact support with the machine ID — there is no documented `show machines` daemon-version field for a preflight `jq` filter today. +4. **Hidden listings:** this loop cannot read whether a listing is hidden. Put every hidden machine in `HIDDEN_IDS`, or leave it off `ALLOWLIST`. Otherwise the first live run makes it publicly searchable. For multiple machines, loop sequentially — do not parallelize without backoff: @@ -385,6 +387,9 @@ export VAST_API_KEY="YOUR_API_KEY" # Set DRY_RUN=0 to apply. # ALLOWLIST required for DRY_RUN=0 (space-separated listed machine IDs). ALLOWLIST="${ALLOWLIST:-}" +# Hidden listings: show machines does not return hidden_listing, and omitting it +# makes the listing public. Put every hidden machine ID here, or leave it off ALLOWLIST. +HIDDEN_IDS="${HIDDEN_IDS:-}" DRY_RUN="${DRY_RUN:-1}" machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do @@ -403,24 +408,33 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do end=$(echo "$machine" | jq -r '.end_date // empty') chunk=$(echo "$machine" | jq -r '.listed_min_gpu_count // empty') disk=$(echo "$machine" | jq -r '.listed_storage_cost // empty') - if [ -z "$price" ] || [ -z "$end" ] || [ -z "$chunk" ] || [ -z "$disk" ]; then - echo "skip $id: missing listed_gpu_cost/end_date/listed_min_gpu_count/listed_storage_cost"; continue + dur=$(echo "$machine" | jq -r '.duration // empty') + if [ -z "$price" ] || [ -z "$chunk" ] || [ -z "$disk" ]; then + echo "skip $id: missing listed_gpu_cost/listed_min_gpu_count/listed_storage_cost"; continue fi - now=$(date -u +%s) - if ! jq -e -n --argjson end "$end" --argjson now "$now" '$end > $now' >/dev/null 2>&1; then - echo "skip machine_id=$id: end_date expired"; continue + if [ -z "$dur" ]; then + if [ -z "$end" ]; then + echo "skip $id: missing end_date and duration"; continue + fi + now=$(date -u +%s) + if ! jq -e -n --argjson end "$end" --argjson now "$now" '$end > $now' >/dev/null 2>&1; then + echo "skip machine_id=$id: end_date expired"; continue + fi fi + hidden=false + if echo "$HIDDEN_IDS" | grep -qw "$id"; then hidden=true; fi # Opt-in only: skip machines with no positive reliability commitment (do not invent 0.99) if ! echo "$machine" | jq -e '(.sla_reliability_claim // 0) > 0' >/dev/null; then echo "skip $id: no positive sla_reliability_claim (enable SLA per machine first)"; continue fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. # price_disk is required: null or omitted resets storage price to 0.10. - # duration is sent when set so an auto-renew listing is not cleared. - body=$(echo "$machine" | jq -c \ + # Send duration OR end_date, never both (400). hidden_listing must be explicit. + body=$(echo "$machine" | jq -c --argjson hidden "$hidden" \ '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, - end_date, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim} - + (if .duration == null then {} else {duration} end)') + min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim, + hidden_listing: $hidden} + + (if .duration == null then {end_date} else {duration} end)') if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi @@ -586,7 +600,7 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi ### Scheduled maintenance -Notify renters in the console ([Set a maintenance window](/host/set-maintenance-window)) or with CLI/REST. After you schedule from the CLI or API, confirm the window under **Host → Machines → Settings → Machine Maintenances**. Do not schedule the same downtime twice. SLA service-credit review looks for at least 24 hours of notice. A service credit is not guaranteed. +Notify renters in the console ([Set a maintenance window](/host/set-maintenance-window)) or with CLI/REST. After you schedule from the CLI or API, confirm the window under **Host → Machines → Settings → Machine Maintenances**. Do not schedule the same downtime twice. Maintenance-forgiveness review looks for at least 24 hours of notice. Forgiveness is not guaranteed, and it does not pay the host. **Console** @@ -595,9 +609,9 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- 2. Set a start at least 24 hours ahead and a duration in whole hours. 3. Confirm the window is listed in that table before you take the machine down. -**Or use CLI/REST below.** A service credit is not guaranteed either way. +**Or use CLI/REST below.** Forgiveness is not guaranteed either way. -**Planned SLA maintenance (renters may qualify for a service credit — not guaranteed):** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Advance notice (not the category value) is what maintenance forgiveness uses. Scheduling earlier counts more of the window as uptime; a longer window counts less. Rescheduling resets the notice clock. Forgiven downtime is not a cash credit to the renter. Renters should check **Instances** for status. It is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. +**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. **`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -619,7 +633,7 @@ REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate"` as U See [CLI install](/cli/hello-world) if you have not set up the CLI. -Planned maintenance credit is not guaranteed. The platform evaluates advance notice (generally at least 24 hours recommended) and maintenance duration when determining credit eligibility. **Treat any scheduled downtime as a potential SLA credit event when modeling risk.** Contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or email [contact@vast.ai](mailto:contact@vast.ai) before extended maintenance on an SLA-listed machine to confirm credit eligibility. +Maintenance forgiveness is not guaranteed. Advance notice and window length determine how much downtime is forgiven. **Treat any scheduled downtime as a potential service-credit event when modeling risk** (you may still owe the renter). Contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or email [contact@vast.ai](mailto:contact@vast.ai) before extended maintenance on an SLA-listed machine to confirm forgiveness eligibility. ## Preview earnings before listing @@ -677,7 +691,7 @@ vastai show earnings --machine_id --start_date "$(date -u -v-7d +%F)T00:00: Keep the `T00:00:00Z` suffix: the CLI parses bare dates such as `2026-07-24` in your machine's local time, so append `T00:00:00Z` for an exact UTC day. On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. -**Linux (GNU date) — one UTC day (compare to the backtester largest single-day credit):** +**Linux (GNU date) — one UTC day (exact settlement check):** ```bash # Replace 12345 with your machine ID. @@ -711,7 +725,7 @@ This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** For exact prior-UTC-day reconciliation (for example vs the backtester largest single-day credit), use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. To cross-check the backtester, compare `sla_earn` with that day's `escrow_to_host_balance`. Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. - **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index e2aae1e5..689c2d38 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -40,14 +40,14 @@ Optional REST body field `maintenance_reason` (short description for notificatio The lowest-risk path is to wait until all active contracts have expired or the machine is vacant, then take the machine offline. -The same `schedule maint` command is used for both **planned** and **emergency** downtime — advance notice and duration determine SLA credit eligibility, not the category value. +The same `schedule maint` command is used for both **planned** and **emergency** downtime — advance notice and duration determine maintenance forgiveness, not the category value. Forgiveness can reduce the service credits you owe. It is not a payment to you. ### Planned SLA maintenance If SLA is enabled and you need planned downtime during an active rental, schedule at least 24 hours in advance. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ```bash -# Replace MACHINE_ID; --sdate must be a future UTC epoch (≥24h ahead for planned credit review) +# Replace MACHINE_ID; --sdate must be a future UTC epoch (≥24h ahead for planned forgiveness review) # Linux: date -u -d '2 days 02:00:00' +%s # macOS: date -u -j -v+2d -v2H -v0M -v0S +%s vastai schedule maint MACHINE_ID \ @@ -64,7 +64,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned SLA credit review). Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned maintenance-forgiveness review). Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. ## Examples diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index b8f6cb33..e09dbe81 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `end_date` is on this method and on that REST call. Volume size, volume price, and duration flags (`-v`, `-z`, `-l` on the CLI) are CLI-only today. Do not send `vol_size`, `vol_price`, or a duration field on that REST call unless the [List Machine](/api-reference/machines/list-machine) schema documents them. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `end_date` is on this method and on that REST call. Volume size, volume price, and duration flags (`-v`, `-z`, `-l` on the CLI) are CLI-only today. Do not send `vol_size` or `vol_price` on that REST call. Follow the read → merge → PUT rule in [Offering SLA](/host/sla-offers): send back `price_disk`, `hidden_listing` when the listing is hidden, and either `duration` (auto-renew) or `end_date`. ## Signature From b8af84e3b4976ccc19249db2a24986e6ec45eb95 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:18:03 -0700 Subject: [PATCH 149/250] docs(sla): address doc-review consensus (cycle 99) Send integer duration in the fleet loop, put reset fields in the listing examples, and use SLA fee consistently. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 4 +- guides/instances/choosing/sla-coverage.mdx | 54 +++++++-------- host/sla-offers.mdx | 79 ++++++++++++---------- 3 files changed, 71 insertions(+), 66 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 1bdda1af..577ce84a 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -6,7 +6,7 @@ sidebarTitle: "search offers" Search for instance types using custom query -Search can quote an SLA. The CLI cannot enable SLA at rent—use the [web console](/guides/instances/choosing/sla-coverage#in-the-web-console) or [API automation](/guides/instances/choosing/sla-coverage#api-automation). Details: [Next step for SLA](#next-step-for-sla). +The CLI can find SLA offers but cannot price them. To see the SLA fee in `dph_total`, search in the console or with REST. The CLI also cannot enable SLA at rent—use the [web console](/guides/instances/choosing/sla-coverage#in-the-web-console) or [API automation](/guides/instances/choosing/sla-coverage#api-automation). Details: [Next step for SLA](#next-step-for-sla). **If you only use the CLI today** @@ -75,7 +75,7 @@ Filter examples (including SLA quotes) are under [Examples](#examples). Query sy ## Examples -**Search quotes SLA pricing only.** Prefer `dph_total` (and `--order dph_total`) when comparing SLA quotes. Match `--storage` to `--disk` if you rent via CLI for non-SLA. To **enable** SLA at rent, see [Next step for SLA](#next-step-for-sla) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**The console and REST quote SLA pricing. The CLI can find SLA offers but cannot price them.** Prefer `dph_total` (and `--order dph_total`) only after a console or REST search that set `target_reliability`. Match `--storage` to `--disk` if you rent via CLI for non-SLA. To **enable** SLA at rent, see [Next step for SLA](#next-step-for-sla) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 8053f9e3..437a087a 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay a small hourly **SLA fee** only after you set a **reliability target** at rent time. If measured uptime falls short of that target, you receive a **service credit**. Search can quote the price; it does not turn the SLA on by itself. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay a small hourly **SLA fee** only after you set a **reliability target** at rent time. If measured uptime falls short of that target, you receive a **service credit**. The console shows that amount as the **SLA Fee** line. API fields call it a premium (for example `slaPremiumPerHour`). Search can show the price; it does not turn the SLA on by itself. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -67,7 +67,7 @@ SLA applies to **on-demand rentals only** — not interruptible/bid or reserved/ -You do not post escrow or collateral for SLA. You pay the SLA charge while your rental contract is active (including during outages, before service credits are applied). Settlement happens automatically on a daily UTC cadence. +You do not post escrow or collateral for SLA. You pay the SLA fee while your rental contract is active (including during outages, before service credits are applied). Settlement happens automatically on a daily UTC cadence. ## What SLA protects @@ -76,7 +76,7 @@ SLA is a **contractual, per-rental** reliability guarantee with automatic daily For on-demand contracts with an SLA: -- You are charged for **compute, storage, and the SLA charge** for the rental day, including periods when the instance is unavailable. +- You are charged for **compute, storage, and the SLA fee** for the rental day, including periods when the instance is unavailable. - Offline time is tracked as an outage in reliability measurements. - If you qualify for compensation, a **service credit** posts after daily settlement (UTC) — typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. @@ -87,16 +87,16 @@ SLA is most useful for **long-running production workloads** where unexpected do Quoted hourly cost with SLA in search (`dph_total`): ``` -dph_total ≈ GPU + storage + SLA charge +dph_total ≈ GPU + storage + SLA fee ``` Bandwidth is billed separately from usage (`inet_*` rates) and is **not** included in `dph_total`. | Factor | What it means for you | | --- | --- | -| Your reliability target | Higher target → higher SLA charge | +| Your reliability target | Higher target → higher SLA fee | | Host reliability commitment | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher commitment → lower SLA fee at a given reliability target | -| Host confidence | Host-side pricing setting that affects SLA charge size. **You do not set this** — the host chooses it, and it is **not shown on offer cards**. Compare offers using `dph_total` or the SLA charge line in the price breakdown | +| Host confidence | Host-side pricing setting that affects SLA fee size. **You do not set this** — the host chooses it, and it is **not shown on offer cards**. Compare offers using `dph_total` or the SLA fee line in the price breakdown | **Rule of thumb:** your reliability target must be **at or below** the host's reliability commitment. Offers whose commitment is below your target are not shown in search and cannot be rented. At the same target, a host with a higher commitment charges a lower SLA fee. In search results, the host reliability commitment appears as **expected reliability** on the offer (API: `expected_reliability`) — not the Reliability Score on the card. @@ -108,7 +108,7 @@ Searching with a **reliability target of 95%** on an offer where the host's **re | --- | --- | | GPU compute | $3.50/hr | | Storage (at search allocation) | ~$0.01/hr | -| SLA charge | ~$0.008/hr | +| SLA fee | ~$0.008/hr | | **Total (`dph_total`)** | ~$3.52/hr | ## Finding SLA offers @@ -136,7 +136,7 @@ Console controls use the same concepts; they do not accept CLI query strings. Us | Filter | Meaning | Example (CLI / API) | | --- | --- | --- | -| `target_reliability` | Your desired reliability level. Also drives SLA charge calculation and ranking. REST and console only (see the Warning below). | REST: `"target_reliability": 0.95` (plain number, not `{"eq": …}`) | +| `target_reliability` | Your desired reliability level. Also drives SLA fee calculation and ranking. REST and console only (see the Warning below). | REST: `"target_reliability": 0.95` (plain number, not `{"eq": …}`) | | `has_sla` | Restrict to offers with (or without) SLA enabled. | `has_sla=true` | | `expected_reliability` | Filter by the host's advertised reliability commitment. | `expected_reliability>=0.99` | @@ -160,19 +160,19 @@ When you set `target_reliability`, search results include: | Response field | Meaning | | --- | --- | -| `search.slaPremiumPerHour` | SLA charge for this offer at your target (API field name) | -| `dph_total` | Total hourly cost **including** the SLA charge | +| `search.slaPremiumPerHour` | SLA fee for this offer at your target (API field name) | +| `dph_total` | Total hourly cost **including** the SLA fee | | `expected_reliability` | Host's reliability commitment | -Hover over the price breakdown on an offer card to see GPU, storage, bandwidth, and the SLA charge separately. +Hover over the price breakdown on an offer card to see GPU, storage, bandwidth, and the SLA fee separately. -When you search with an SLA target, reserved-instance discounts may not apply to the displayed total. Confirm in the console price breakdown. SLA charges are never discounted. +When you search with an SLA target, reserved-instance discounts may not apply to the displayed total. Confirm in the console price breakdown. SLA fees are never discounted. ### Comparing offers -| Offer | GPU/hr | Host commitment | Your target | SLA charge/hr | +| Offer | GPU/hr | Host commitment | Your target | SLA fee/hr | | --- | --- | --- | --- | --- | | A | $3.50 | 99% | 95% | ~$0.008 | | B | $3.50 | 95% | 95% | much higher | @@ -288,13 +288,13 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | --- | --- | --- | | Offer has no SLA, target is above the host commitment, target is out of range, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | | SLA not enabled for the account or region | HTTP 403 `sla_disabled` | Contact support | -| Offer no longer exists | HTTP 400 `invalid_args`, message `no_such_ask` | Re-search and use a fresh offer ID | +| Offer no longer exists | HTTP 400 `invalid_args` / `no_such_ask`, HTTP 404, or HTTP 410 | Re-search and use a fresh offer ID | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | Before sending the same `PUT` again, check `GET /api/v1/instances/` for a new contract. There is no idempotency key, so a blind retry can create a second paid rental. | -| Too many requests | HTTP 429 | Wait and back off. Before retrying the same `PUT`, confirm with `GET /api/v1/instances/` whether the contract already exists. If retry returns `invalid_price`, `no_such_ask`, 404, or 410, re-search with the same `target_reliability` and storage, then rent a fresh offer id. | +| Too many requests | HTTP 429. Search is about 10 requests per minute. Rent uses `threshold` 4.5; the body is `{"detail": ...}`, not `{success, error, msg}`. | Back off, then confirm with `GET /api/v1/instances/` whether the contract already exists. If retry returns `invalid_price`, `no_such_ask`, 404, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | -| Forbidden / wrong account | HTTP 400 `invalid_args` from a host account | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | +| Forbidden / wrong account | HTTP 403 `invalid_args` ("Hosts can only rent their own machines.") | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | | Channel | Default storage | Field | Units (label) | | --- | --- | --- | --- | @@ -312,15 +312,15 @@ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** be When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA charge line or `dph_total`. Host confidence is not shown in the web console and is not a setting you control. -2. **Daily billing** — you pay compute plus the SLA charge each day. +1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA fee line or `dph_total`. Host confidence is not shown in the web console and is not a setting you control. +2. **Daily billing** — you pay compute plus the SLA fee each day. 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. -4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA charge with no credit. +4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA fee with no credit. ### What you pay during an outage -Billing continues during downtime. You are still charged for **compute, storage, and the SLA charge** while the contract exists and the instance is unavailable. Leaving a broken instance running continues those charges until you destroy it. +Billing continues during downtime. You are still charged for **compute, storage, and the SLA fee** while the contract exists and the instance is unavailable. Leaving a broken instance running continues those charges until you destroy it. **Stop vs destroy:** Stopping pauses compute but storage and contract charges can continue. **Destroying the instance** ends future daily charges; final SLA settlement still posts when the contract closes. If you abandon a failed host, destroy only after saving any data you need. @@ -339,9 +339,9 @@ When a host schedules maintenance in advance, part of that downtime is counted a ### Credit scenarios (simplified) -Using the H100 example ($84/day compute, ~$0.20/day SLA charge, target 95%, host reliability commitment 99%): +Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host reliability commitment 99%): -| Scenario | Approx. SLA charge | Approx. service credit | Net vs no SLA (approx.) | +| Scenario | Approx. SLA fee | Approx. service credit | Net vs no SLA (approx.) | | --- | --- | --- | --- | | Above target (excellent / good day) | ~$0.20/day | $0 | **−$0.20** (you paid the SLA fee) | | Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (net credit after SLA fee) | @@ -364,7 +364,7 @@ Production settlement uses the multi-window reliability blend described above, n ## If your instance goes down 1. Save work and check **Instances** for host/maintenance status. -2. Remember: compute, storage, and SLA charges continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. +2. Remember: compute, storage, and SLA fees continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. 3. **Console:** Open **Instances**, select the instance, then **Destroy** to stop future charges. Stopping alone may not end billing for a broken instance—see [Stop vs destroy](#what-you-pay-during-an-outage). Destroy permanently deletes the instance and its disk, so copy off anything you need first. 4. After settlement, check **Account → Billing** in the console for SLA line items (not `GET /api/v0/charges/`). 5. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). @@ -375,11 +375,11 @@ Production settlement uses the multi-window reliability blend described above, n 1. Open **Instances** and select your running instance. 2. Open **price details** (or the instance billing panel) and confirm an **SLA Fee** line is present. -3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. If you do not see a target or SLA charge, you likely rented without the SLA. +3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. If you do not see a target or SLA fee, you likely rented without the SLA. ### API integrators -Console users: open **Instances** → select your instance → **price details** to confirm the SLA charge and target. Skip the block below if you do not use the API. +Console users: open **Instances** → select your instance → **price details** to confirm the SLA fee and target. Skip the block below if you do not use the API. **Common mistake:** `vastai show instances` (v0) and `GET /api/v0/instances/{id}/` do not return SLA fields. Verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. Enabling SLA still requires console or REST — see [Finding SLA offers](#finding-sla-offers). @@ -399,7 +399,7 @@ To find instances with an SLA, post-process the API response in your application | Concept | Search / bundles | After rent (`GET /api/v1/instances/`) | | --- | --- | --- | | Your reliability target | `target_reliability` (quote only until rent) | `target_reliability` | -| SLA charge rate | `search.slaPremiumPerHour` | `instance.slaPremiumPerHour` | +| SLA fee rate | `search.slaPremiumPerHour` | `instance.slaPremiumPerHour` | **Host-locked on contract (read-only)** @@ -407,7 +407,7 @@ To find instances with an SLA, post-process the API response in your application | --- | --- | --- | | Host reliability commitment | `expected_reliability` | `sla_r_claim` | -Host ask field `sla_r_claim` on listings is host-side; on active rentals the locked reliability commitment appears as `sla_r_claim` in show-instances. Host confidence is **not shown on offer cards** — compare offers using `dph_total` or the SLA charge line. Confirm field names against a live `--raw` response before building parsers. +Host ask field `sla_r_claim` on listings is host-side; on active rentals the locked reliability commitment appears as `sla_r_claim` in show-instances. Host confidence is **not shown on offer cards** — compare offers using `dph_total` or the SLA fee line. Confirm field names against a live `--raw` response before building parsers.
## When SLA is not available diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 29c0fe13..56006d08 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -4,7 +4,9 @@ description: "Offer an SLA on your machines: set a reliability commitment and co "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose an SLA pay a small hourly **SLA charge** included in **`dph_total`** (dollars per hour total in search — GPU + storage + SLA charge), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose an SLA pay a small hourly **SLA fee** included in **`dph_total`** (dollars per hour total in search — GPU + storage + SLA fee), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. + +The **SLA fee** is that hourly amount. It appears as the **SLA Fee** line in the console. API field names call the same amount a premium (for example `slaPremiumPerHour`). **New to SLA?** Read [SLA in plain language](#sla-in-plain-language) first, then return here for economics and API detail. @@ -67,7 +69,7 @@ Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machin Before enabling SLA, finish normal listing setup: test your machine, set GPU price and offer end date, choose on-demand vs interruptible, and understand [Testing your own machine](/host/hosting-overview#testing-your-own-machine) and offer terms in [Hosting overview](/host/hosting-overview). -On outage days you may still bill clients for **intended** compute **and** owe service credits. Tail-risk exposure can approach a full day’s compute per affected contract — not just the daily SLA charge shown in previews. Read [Billing vs settlement](#billing-vs-settlement-important) before enabling SLA. +On outage days you may still bill clients for **intended** compute **and** owe service credits. Tail-risk exposure can approach a full day’s compute per affected contract — not just the daily SLA fee shown in previews. Read [Billing vs settlement](#billing-vs-settlement-important) before enabling SLA. @@ -112,17 +114,17 @@ Clients choose their own **reliability target** at search and rent time. You do Think of an SLA offer as two host ideas plus one client choice: 1. **Your reliability commitment** — what you believe your machine will deliver (`sla_r_claim`). Setting this above `0` enables SLA on the offer. -2. **Your confidence** — how wide your belief is around that reliability commitment (`sla_sigma_x`). Tighter confidence → lower SLA charges for clients at a given target; wider confidence → higher charges. +2. **Your confidence** — how wide your belief is around that reliability commitment (`sla_sigma_x`). Tighter confidence → lower SLA fees for clients at a given target; wider confidence → higher charges. 3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA fee sizing use this target. A renter's target must be **at or below** your reliability commitment. Search hides offers whose commitment is below the target, and rent rejects that combination. When a client rents an on-demand instance on your SLA-listed offer with a chosen target: -- While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA charge** — including during downtime. Settlement credits for missed targets are calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA charge at the quoted allocation — **not** bandwidth. +- While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA fee** — including during downtime. Settlement credits for missed targets are calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA fee at the quoted allocation — **not** bandwidth. - Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. -- **Strong reliability relative to the client's target** → you keep the SLA charge for that day. +- **Strong reliability relative to the client's target** → you keep the SLA fee for that day. - **Shortfalls** → credits flow to the client from your earnings (bounded by that day's covered compute). -Over many strong days, SLA charges can offset occasional credits, but a single bad day can exceed months of collected charges — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. +Over many strong days, SLA fees can offset occasional credits, but a single bad day can exceed months of collected charges — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. ### How reliability is measured @@ -146,7 +148,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | | Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.99999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | -| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA charges for clients at a given target). Defaults to `0.5` if omitted. | +| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA fees for clients at a given target). Defaults to `0.5` if omitted. | ### Advanced: `sla_max_beta` (optional) @@ -164,9 +166,9 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Reliability commitment | Claim | `sla_r_claim` | `r_claim` | `expected_reliability` | | Confidence | Confidence / spread | `sla_sigma_x` | `p` (different scale) | — | | Reliability target | — (client-chosen) | — (not on asks) | `r_target` (optional; defaults to `r_claim`) | `target_reliability` in search | -| All-in hourly price | — | — | — | `dph_total` (compute plus SLA charge when enabled) | +| All-in hourly price | — | — | — | `dph_total` (compute plus SLA fee when enabled) | -**Confidence is not an uptime target.** It controls how aggressively SLA charges are priced around your reliability commitment. +**Confidence is not an uptime target.** It controls how aggressively SLA fees are priced around your reliability commitment.
### Machine reliability score vs SLA reliability @@ -175,23 +177,23 @@ The **reliability score** on the Host Machines page reflects connection and inst Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r_claim`: -1. Open **Host → Machines** → **Set Pricing → SLA** and review the console SLA charge preview at candidate reliability commitments. +1. Open **Host → Machines** → **Set Pricing → SLA** and review the console SLA fee preview at candidate reliability commitments. 2. If you have rental history, run the [backtester](/host/sla-backtester) and compare `r_eff` (effective reliability) with `r_be` (break-even reliability) in the response. -3. Set **reliability commitment** at a level you can sustain; clients who pick targets below your reliability commitment see lower SLA charges. +3. Set **reliability commitment** at a level you can sustain; clients who pick targets below your reliability commitment see lower SLA fees. ### Confidence values -**This only changes how SLA charges are priced — it does not change how reliability is measured or what credit you owe when a client's target is missed.** Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. +**This only changes how SLA fees are priced — it does not change how reliability is measured or what credit you owe when a client's target is missed.** Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. | Console label | API `sla_sigma_x` | Backtester `p` | Pricing effect | | --- | --- | --- | --- | -| Tight | `0.2` | ~0.83 | Lowest client SLA charges at a given target | +| Tight | `0.2` | ~0.83 | Lowest client SLA fees at a given target | | Normal (default) | `0.5` | ~0.6667 | Balanced | -| Wide | `1.0` | ~0.50 | Highest client SLA charges at a given target | +| Wide | `1.0` | ~0.50 | Highest client SLA fees at a given target | **Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). -**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA charges (more competitive `dph_total`). **Wider confidence** (console label **Wide**) → higher client SLA charges. Confidence does **not** change the credit formula when a target is missed — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. +**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA fees (more competitive `dph_total`). **Wider confidence** (console label **Wide**) → higher client SLA fees. Confidence does **not** change the credit formula when a target is missed — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. ### Validation rules @@ -229,7 +231,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. 4. Set your **reliability commitment** (the console control is **Claim**; the API field is `sla_r_claim`). Renters see it as expected reliability on the offer. Set **Confidence** too. For your first listing, choose **Normal** (`sla_sigma_x ≈ 0.5`) unless your uptime history is volatile — see [Confidence values](#confidence-values) for risk tradeoffs. -5. Save and confirm the SLA charge preview before listing. +5. Save and confirm the SLA fee preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. #### Updating SLA on an already-listed machine @@ -240,7 +242,7 @@ If the machine is already **listed**: 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. 3. Verify after listing: - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. - - **Search:** `dph_total` includes the SLA charge at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). + - **Search:** `dph_total` includes the SLA fee at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same publish step as **LIST**; SLA parameters require this REST body or **Set Pricing → SLA**, not `vastai list machine` flags). @@ -248,7 +250,7 @@ In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIS #### Web console SLA preview -In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA charge and service-credit exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA fee and service-credit exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. ### API (for automation) @@ -276,10 +278,10 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": 0.15, "hidden_listing": false, "end_date": 1893456000, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `price_disk` with the machine's current `listed_storage_cost` from `vastai show machines --raw`. Also send `duration` if the listing auto-renews, otherwise `end_date`, and `"hidden_listing": true` if it is hidden. See the read → merge → PUT warning below. Do not copy example prices into a first listing. +Replace `price_disk` with the machine's current `listed_storage_cost`. Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. #### Full listing update (existing ask) @@ -293,6 +295,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ "machine": 12345, "price_gpu": 3.50, "price_disk": 0.15, + "hidden_listing": false, "sla_r_claim": 0.99, "sla_sigma_x": 0.5, "end_date": 1893456000 @@ -310,6 +313,7 @@ SLA fields example (existing listing, same limit as the curl above): "machine": 12345, "price_gpu": 3.50, "price_disk": 0.15, + "hidden_listing": false, "end_date": 1893456000, "sla_r_claim": 0.99, "sla_sigma_x": 0.5 @@ -429,12 +433,13 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. # price_disk is required: null or omitted resets storage price to 0.10. - # Send duration OR end_date, never both (400). hidden_listing must be explicit. + # Send duration OR end_date, never both (400). duration must be an integer; + # show machines returns a float, which the API rejects. hidden_listing must be explicit. body=$(echo "$machine" | jq -c --argjson hidden "$hidden" \ '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim, hidden_listing: $hidden} - + (if .duration == null then {end_date} else {duration} end)') + + (if .duration == null then {end_date} else {duration: (.duration | floor)} end)') if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi @@ -457,13 +462,13 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid -**SLA-only update (existing ask only)** — include `machine`, the current `price_disk`, and the SLA fields. Do **not** use this body for a first listing. Replace `0.15` with `listed_storage_cost`. +**SLA-only update (existing ask only)** — send `machine`, the current `price_disk`, `hidden_listing`, and either `duration` (integer seconds) or `end_date`, plus the SLA fields. Omitted fields reset as described in the warning above. Do **not** use this body for a first listing. Replace the placeholders with values from `show machines`. ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' + -d '{"machine": 12345, "price_disk": 0.15, "hidden_listing": false, "end_date": 1893456000, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` **Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. @@ -514,21 +519,21 @@ SLA field updates apply to the **offer** and to **new** rentals only. Existing r | Item | Amount | | --- | --- | | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr GPU only — simplified) | -| SLA charge (client pays) | ~**$0.008/hr** (~$0.20/day at 24 hr) | +| SLA fee (client pays) | ~**$0.008/hr** (~$0.20/day at 24 hr) | SLA credits are capped relative to that UTC day's covered compute — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat the [largest single-day credit](/host/sla-backtester#summarize-with-jq) from the SLA backtester as the authoritative tail-risk figure before you list. -SLA charge sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview single-day credit exposure (largest single-day credit) and break-even reliability (`r_be`), not exact client SLA charges. For authoritative client-visible charges, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers at a chosen `target_reliability`. +SLA fee sizing uses internal SLA math. Use the [SLA backtester](/host/sla-backtester) to preview single-day credit exposure (largest single-day credit) and break-even reliability (`r_be`), not exact client SLA fees. For authoritative client-visible charges, use **Set Pricing → SLA** in the console or **`dph_total`** in search offers at a chosen `target_reliability`. -If you omit `r_target`, the backtester sets the renter target equal to your reliability commitment (`r_claim`), which is a **conservative** what-if (as if every client targeted your reliability commitment). Pass `r_target` to model clients who choose lower targets; they usually see lower SLA charges. Use the backtester's largest single-day credit as your worst single-day credit reference, then verify visible charges in **Set Pricing → SLA** (or `dph_total` in search) before listing. +If you omit `r_target`, the backtester sets the renter target equal to your reliability commitment (`r_claim`), which is a **conservative** what-if (as if every client targeted your reliability commitment). Pass `r_target` to model clients who choose lower targets; they usually see lower SLA fees. Use the backtester's largest single-day credit as your worst single-day credit reference, then verify visible charges in **Set Pricing → SLA** (or `dph_total` in search) before listing. ### Search / client-visible fields When SLA is enabled on an offer, clients see: -- **`dph_total`** — total $/hour including the SLA charge at their `target_reliability` (authoritative for client-visible all-in pricing). +- **`dph_total`** — total $/hour including the SLA fee at their `target_reliability` (authoritative for client-visible all-in pricing). - **`expected_reliability`** — your advertised reliability commitment (maps to `sla_r_claim`). - **`reliability` / `reliability2`** — historical machine reliability scores, **not** your reliability commitment. @@ -543,14 +548,14 @@ vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 - ### If reliability is strong relative to the client's target -In the **You net** column, values follow host earnings sign conventions: positive means SLA charge you kept; negative means credit you owed the client. +In the **You net** column, values follow host earnings sign conventions: positive means SLA fee you kept; negative means credit you owed the client. | Measured reliability (simplified) | You net (per day) | | --- | --- | -| ~100% (excellent day) | +$0.20 (keep SLA charge) | -| ~99% (good day) | +$0.17 (keep most of the SLA charge) | +| ~100% (excellent day) | +$0.20 (keep SLA fee) | +| ~99% (good day) | +$0.17 (keep most of the SLA fee) | -You keep most or all of the SLA charge. +You keep most or all of the SLA fee. ### What if measured reliability is between the client's target and my reliability commitment? @@ -558,14 +563,14 @@ Example: you publish **reliability commitment 99%**, the client chose **target 9 - **Credits** are evaluated against the client's **target** (95%), not your reliability commitment. - Because 97% is above 95%, you typically **owe no SLA credit** for that day. -- **SLA charges** are priced from your **reliability commitment**, confidence, and the client's target — a higher reliability commitment relative to the target generally means lower client charges. +- **SLA fees** are priced from your **reliability commitment**, confidence, and the client's target — a higher reliability commitment relative to the target generally means lower client charges. The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what drives service-credit eligibility. ### If the client's target is missed -Credits scale relative to the day's compute, not only the SLA charge collected. A single bad day near the client's target boundary can cost as much as 200+ days of collected SLA charges. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. +Credits scale relative to the day's compute, not only the SLA fee collected. A single bad day near the client's target boundary can cost as much as 200+ days of collected SLA fees. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. These scenarios show settlement when reliability **drops to or below** a 95% client target — they are boundary illustrations, not typical strong days: @@ -575,7 +580,7 @@ These scenarios show settlement when reliability **drops to or below** a 95% cli | Just below target on the blended measure (daily uptime may look close to 95%) | −$42 (credit you owe) | | Well below target (~90% or less) | −$84 (large credit owed) | -To put the asymmetry in perspective: at ~$0.20/day in SLA charges, it takes roughly 210 strong days to accumulate the $42 you could lose on a single day at the target boundary. The SLA charge is a small fraction of daily compute, while credits scale against total daily compute. +To put the asymmetry in perspective: at ~$0.20/day in SLA fees, it takes roughly 210 strong days to accumulate the $42 you could lose on a single day at the target boundary. The SLA fee is a small fraction of daily compute, while credits scale against total daily compute. Your maximum SLA loss on any single settlement day is bounded by that day's covered compute (GPU, storage, and bandwidth). @@ -583,7 +588,7 @@ Your maximum SLA loss on any single settlement day is bounded by that day's cove ### Reliability commitment 99%, delivered 99.5% -You outperform your reliability commitment. Clients who chose targets at or below 99% pay small SLA charges; credits are rare. You net positive on SLA over time. +You outperform your reliability commitment. Clients who chose targets at or below 99% pay small SLA fees; credits are rare. You net positive on SLA over time. ### Reliability commitment 99% with an offline day @@ -591,7 +596,7 @@ Clients receive credits tied to how far measured reliability falls below **their ### Clients target near your reliability commitment -SLA charges are **much higher** when the client's target sits near your reliability commitment (little headroom). Prefer a reliability commitment you can sustain above the targets clients actually choose. +SLA fees are **much higher** when the client's target sits near your reliability commitment (little headroom). Prefer a reliability commitment you can sustain above the targets clients actually choose. ### You widen confidence (`sla_sigma_x` → 1.0) From 4c8a7568fc323cda53094ab17d745f447e4b21cd Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:22:23 -0700 Subject: [PATCH 150/250] docs(sla): fix backtester fleet scripts and field semantics (lane review 1) show machines hides SLA terms unless the platform switch, listing, host approval, and daemon version all allow it, and returns 0 when SLA is off, so the fleet loops now treat 0/null as absent and log every R/P fallback. Also document that beta is accepted-and-ignored, the exact p = 1/(1 + sla_sigma_x) mapping (sigma clamped at 3.0), raw vs blended reliability, and what r_eff's "no deposits" means. Co-Authored-By: Claude Opus 5.5 (1M context) --- host/sla-backtester.mdx | 30 ++++++++++++++++++++---------- host/sla-offers.mdx | 4 ++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index a65dd4fd..579d5d8e 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -52,7 +52,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). **Simulation limits** - The whole machine is replayed as one contract. Live settlement runs per rental contract, so several concurrent SLA renters on a sliced machine can produce more credits on one day than the simulation shows. Pair this output with [SLA and GPU slicing](/host/sla-offers#sla-and-gpu-slicing). -- For renter-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or search with a realistic `target_reliability`. +- For renter-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or a REST search with a realistic `target_reliability` (the CLI cannot send `target_reliability` today). - How recent versus long-term uptime is weighted is set automatically from the renter target. It is not a host setting; the value used is echoed in `params.beta`. @@ -88,7 +88,7 @@ Requires Bearer authentication. Rate-limited to about one request every two seco | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | -Any other query parameter is rejected with `400 bad_request`. The older `r` and `reliability` parameters are no longer accepted; use `r_claim` (and `r_target`). +`beta` is accepted but ignored for host accounts; the value actually used is echoed in `params.beta`. Any other unknown query parameter is rejected with `400 bad_request`. The older `r` and `reliability` parameters are no longer accepted; use `r_claim` (and `r_target`). ### Limits @@ -177,7 +177,7 @@ A successful response looks like this (one `days` row shown; values are illustra | --- | --- | | `has_data` | `true` if the range had at least one day of rental earnings to replay. When `false`, every `days` row is zero with `reliability: null`, and `r_eff` is `null`. Try a wider window or a machine with more rental history. | | `start_day`, `end_day` | UTC day indices, `day = floor(epoch_seconds / 86400)`. `day × 86400` is exactly 00:00 UTC on that date. Convert with `date -u -d "@$((day * 86400))" +%F` (Linux) or `date -u -r $((day * 86400)) +%F` (macOS). Show Earnings `sday` / `eday` use the same day index. | -| `r_eff` | **Effective reliability**: the constant reliability that would have produced the service credits paid in this window. `null` when the window had no deposits. | +| `r_eff` | **Effective reliability**: the constant reliability that would have produced the service credits paid in this window. `null` when nothing was paid into escrow in the window (all `client_*_to_escrow` values are zero, as with `has_data: false`). | | `r_be` | **Break-even reliability**: the reliability at which SLA fees and service credits cancel out. Always present. | | `days` | One row per UTC day from `start_day` to `end_day` (see below). | | `params` | The SLA terms the replay actually used: `r_claim`, `r_target` (after defaulting), `p`, and the automatically derived `beta`. | @@ -191,11 +191,13 @@ Every value is money (in $) that moved on that day. All flows are zero or positi | Field | Meaning | | --- | --- | | `day` | UTC day index | -| `client_compute_to_escrow` | The renter's compute payment for the day, held in escrow (your net earnings after the platform fee) | +| `client_compute_to_escrow` | The renter's compute payment for the day, net of the platform fee, held in escrow (what would reach you if there were no credits) | | `client_premium_to_escrow` | The SLA fee paid in for the day | | `escrow_to_client_balance` | Service credits paid to the renter that day | | `escrow_to_host_balance` | Money released from escrow to you that day | -| `reliability` | Measured uptime fraction for the day (0–1), or `null` when the machine had no rental data that day | +| `reliability` | Raw measured uptime fraction for the day (0–1), or `null` when the machine had no rental data that day | + +`reliability` is that day's raw uptime. Credits settle on the blended recent-plus-longer-term measure (see [SLA in plain language](/host/sla-offers#sla-in-plain-language)), so a day can carry a credit even when its `reliability` is at or above `r_target`. Releases to you are spread over time rather than paid out the same day, and the final active day includes the contract's closing settlement. Read individual days as cash movement, not as that day's profit or loss. @@ -238,6 +240,8 @@ A single outage day can cost far more than many days of fees. Check that you can **`p` and `sla_sigma_x` use different scales** — do not copy numeric values between them. For example, `p=0.5` (Wide) maps to `sla_sigma_x ≈ 1.0`, not `0.5`. Use the table below to translate between the two. +The two values are exactly related: `p = 1 / (1 + sla_sigma_x)`, and `sla_sigma_x = 1/p − 1`. To backtest a custom `sla_sigma_x`, pass `p = 1/(1 + sla_sigma_x)` (for example `sla_sigma_x` 0.3 → `p` 0.7692). `sla_sigma_x` is capped at 3.0, so any `p` at or below 0.25 behaves like `p=0.25`. + | Confidence `p` | Console label | Listing equivalent | | --- | --- | --- | | `0.83` | Tight | `sla_sigma_x ≈ 0.2` | @@ -274,7 +278,11 @@ Optional, for API automation only. To check one machine, use the single-machine **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). -1. Run backtests **sequentially**, one machine at a time. The loop reads each machine's `sla_reliability_claim` and `sla_confidence` label from `show machines`. For machines that don't have SLA yet, set `R` (commitment) and `P` (confidence `p`) to backtest them before you enable SLA. Machines with neither are skipped and logged. The confidence label is a band, so a custom `sla_sigma_x` is backtested at the nearest band's `p`; backtest that machine with the single-machine request to test an exact `p`. +1. Run backtests **sequentially**, one machine at a time: + - The loop reads each machine's `sla_reliability_claim` and `sla_confidence` label from `show machines`. + - For machines whose terms are not visible, set `R` (commitment) and `P` (confidence `p`) as fallbacks. That covers machines without SLA yet, and machines whose terms are hidden because they are unlisted, have an outdated daemon, or lack SLA approval. The loop logs every fallback it uses, so check those rows before trusting them. + - Machines missing either value, with no `R`/`P` fallback, are skipped and logged. + - The confidence label is a band, so a custom `sla_sigma_x` is backtested at the nearest band's `p`. To test an exact value, use the single-machine request with `p = 1/(1 + sla_sigma_x)`. 2. Responses are written to a private temp directory that is deleted when the loop exits. ```bash @@ -286,10 +294,11 @@ machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') - r=$(echo "$machine" | jq -r '.sla_reliability_claim // empty') - r="${r:-${R:-}}" # R only fills in for machines without SLA terms + # Treat 0 (SLA off) and null (terms hidden) as absent; R only fills in for those machines. + r=$(echo "$machine" | jq -r '(.sla_reliability_claim // 0) | if . > 0 then . else empty end') + if [ -z "$r" ] && [ -n "${R:-}" ]; then r="$R"; echo "machine $id: using fallback R=$R" >&2; fi if ! jq -e -n --arg r "$r" 'try (($r | tonumber) > 0) catch false' >/dev/null 2>&1; then - echo "skip $id: no sla_reliability_claim; set R=0.99 (or your planned commitment) to backtest before enabling SLA"; continue + echo "skip $id: no SLA terms visible; set R=0.99 (or your planned commitment) as a fallback"; continue fi # show machines returns confidence as a label: high = Tight, medium = Normal, low = Wide. # P only fills in for machines without SLA terms. @@ -297,7 +306,8 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do high) p=0.83 ;; medium) p=0.6667 ;; low) p=0.50 ;; - *) p="${P:-}" ;; + *) p="${P:-}" + [ -n "$p" ] && echo "machine $id: using fallback P=$P (sla_confidence null)" >&2 ;; esac if [ -z "$p" ]; then echo "skip $id: no sla_confidence; set P=0.6667 (Normal) to backtest before enabling SLA"; continue diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 56006d08..fed78cb0 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -342,7 +342,7 @@ vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12 REST equivalent: `GET /api/v0/machines/` (the CLI sends `?owner=me`). The account is the API key owner; a `?user_id=` query is ignored. -Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence` (`high` = Tight, `medium` = Normal, `low` = Wide), not as `sla_sigma_x`. The SLA fields are `null` unless the machine is listed with SLA terms. Pricing fields and `end_date` are `null` when the machine is not listed. +Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence` (`high` = Tight, `medium` = Normal, `low` = Wide), not as `sla_sigma_x`. `sla_reliability_claim` and `sla_confidence` are `null` unless **all** of these are true: SLA is enabled on the platform, the machine is listed, your account is SLA-approved, and the machine's daemon meets the SLA minimum version. A machine with saved SLA terms can still return `null` if it is unlisted, its daemon is outdated, or approval was revoked. A listed machine with SLA turned off returns `0`. Pricing fields and `end_date` are `null` when the machine is not listed. Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge → PUT). `vastai list machine` and the Python SDK listing helpers cannot set SLA fields; start from this REST pattern (or the console) when you move an existing CLI listing to SLA. @@ -429,7 +429,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if echo "$HIDDEN_IDS" | grep -qw "$id"; then hidden=true; fi # Opt-in only: skip machines with no positive reliability commitment (do not invent 0.99) if ! echo "$machine" | jq -e '(.sla_reliability_claim // 0) > 0' >/dev/null; then - echo "skip $id: no positive sla_reliability_claim (enable SLA per machine first)"; continue + echo "skip $id: no SLA terms visible (SLA off, daemon below SLA minimum, or account not SLA-approved)"; continue fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. # price_disk is required: null or omitted resets storage price to 0.10. From 5cf3cee98cfb2f5631481c84dcc540f84c85edcf Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:25:36 -0700 Subject: [PATCH 151/250] docs(sla): address doc-review consensus (cycle 100) Stop copy-paste end dates from extending live contracts, and align fee, credit, and maintenance wording with settlement. Co-authored-by: Cursor --- api-reference/openapi.yaml | 7 ++- .../openapi/yaml/schedule_maint.yaml | 4 +- guides/instances/choosing/sla-coverage.mdx | 8 +-- host/sla-offers.mdx | 52 +++++++++++++------ snippets/host/cli/schedule-maint.mdx | 2 +- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index d33485f4..2401bcd4 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6418,7 +6418,12 @@ paths: example: 2 maintenance_reason: type: string - description: Reason for the maintenance. + description: 'Accepted on the request schema, but the server currently + stores this + + field empty. Renters will not see a reason you send. + + ' example: Routine hardware check maintenance_category: type: string diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index 5cf47099..8304407e 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -46,7 +46,9 @@ paths: example: 2 maintenance_reason: type: string - description: Reason for the maintenance. + description: | + Accepted on the request schema, but the server currently stores this + field empty. Renters will not see a reason you send. example: Routine hardware check maintenance_category: type: string diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 437a087a..8503d461 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay a small hourly **SLA fee** only after you set a **reliability target** at rent time. If measured uptime falls short of that target, you receive a **service credit**. The console shows that amount as the **SLA Fee** line. API fields call it a premium (for example `slaPremiumPerHour`). Search can show the price; it does not turn the SLA on by itself. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay a small hourly **SLA fee** on top of compute only after you set a **reliability target** at rent time. The console shows that fee as the **SLA Fee** line. API fields call it a premium (for example `slaPremiumPerHour`). If measured uptime falls short of your target, you receive a **service credit**, shown as **Service Credit** in Account → Billing. Search can show the price; it does not turn the SLA on by itself. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -16,7 +16,7 @@ An SLA is an optional reliability promise on an **on-demand** GPU rental. You do 2. **You** choose a **reliability target**: how much uptime you want. A higher target costs more. 3. You pay an **SLA fee** (a service level fee) on top of the GPU price. 4. Each day, Vast checks how long your instance was actually up. -5. If uptime met your reliability target, the host keeps the SLA fee. "Met" is judged on Vast's blended reliability measure (recent and longer-term uptime), not on a single day's raw uptime. Settlement is graduated: a day that looks close to the target can still produce a partial credit. +5. If the blended measure met your reliability target, the host keeps the SLA fee. "Met" uses Vast's blended reliability measure (recent and longer-term uptime), not that day's raw uptime alone. A day whose raw uptime is at or slightly above your target can still produce a partial credit if the blended measure falls below it. 6. If uptime missed your reliability target, you receive a **service credit**. That credit can be larger than the SLA fee you paid that day. A few things people mix up: @@ -294,7 +294,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | Before sending the same `PUT` again, check `GET /api/v1/instances/` for a new contract. There is no idempotency key, so a blind retry can create a second paid rental. | | Too many requests | HTTP 429. Search is about 10 requests per minute. Rent uses `threshold` 4.5; the body is `{"detail": ...}`, not `{success, error, msg}`. | Back off, then confirm with `GET /api/v1/instances/` whether the contract already exists. If retry returns `invalid_price`, `no_such_ask`, 404, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | -| Forbidden / wrong account | HTTP 403 `invalid_args` ("Hosts can only rent their own machines.") | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | +| Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | | Channel | Default storage | Field | Units (label) | | --- | --- | --- | --- | @@ -425,7 +425,7 @@ No. For short experiments or fault-tolerant batch jobs, standard on-demand renta ### Can I change my reliability target mid-rental? -No. The target is fixed when the contract is created. End the instance and rent again with a different search filter if you need a different level. +No. The target is fixed when the contract is created. **Destroy** the instance (this deletes its disk; the same machine may not be available again) and rent again with a different **Reliability target**. ### Does SLA replace verification? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index fed78cb0..0e2c3464 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -88,7 +88,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. If uptime met their reliability target, you keep the SLA fee. "Met" is judged on Vast's blended reliability measure (recent and longer-term uptime), not on a single day's raw uptime. Settlement is graduated: a day that looks close to the target can still produce a partial credit. +6. If the blended measure met their reliability target, you keep the SLA fee. "Met" uses Vast's blended reliability measure (recent and longer-term uptime), not that day's raw uptime alone. A day whose raw uptime is at or slightly above the target can still produce a partial credit if the blended measure falls below it. When the blended measure meets the target, no credit is paid. 7. If uptime missed their reliability target, the renter receives a **service credit** from your earnings. One bad day can cost more than many days of fees. What this is not: @@ -173,7 +173,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / ### Machine reliability score vs SLA reliability -The **reliability score** on the Host Machines page reflects connection and instance-start behavior over recent activity. **SLA settlement** measures whether covered instances met the client's published uptime target for billing purposes. +The **reliability score** on the Host Machines page reflects connection and instance-start behavior over recent activity. **SLA settlement** measures whether covered instances met the renter's chosen reliability target for billing purposes. Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r_claim`: @@ -278,10 +278,14 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "hidden_listing": false, "end_date": 1893456000, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": 0.15, "hidden_listing": false, "end_date": "CURRENT_END_DATE_FROM_SHOW_MACHINES", "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `price_disk` with the machine's current `listed_storage_cost`. Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. +Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `end_date` with the machine's **current** `end_date` from `show machines` (a Unix timestamp, not the placeholder string). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. + + +Send your **current** `end_date` unless you intend to extend. A later `end_date` at the same or lower price extends existing rental contracts, including their SLA terms and service-credit exposure. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). + #### Full listing update (existing ask) @@ -298,11 +302,11 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ "hidden_listing": false, "sla_r_claim": 0.99, "sla_sigma_x": 0.5, - "end_date": 1893456000 + "end_date": "CURRENT_END_DATE_FROM_SHOW_MACHINES" }' ``` -Replace `end_date` with a **future** Unix timestamp — past dates expire the offer immediately (example `1893456000` = 2030-01-01 00:00 UTC). Set `end_date` so the offer does not stay open indefinitely — especially important for SLA commitments. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`. +Replace `end_date` with the listing's current Unix timestamp from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`. Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). @@ -314,7 +318,7 @@ SLA fields example (existing listing, same limit as the curl above): "price_gpu": 3.50, "price_disk": 0.15, "hidden_listing": false, - "end_date": 1893456000, + "end_date": "CURRENT_END_DATE_FROM_SHOW_MACHINES", "sla_r_claim": 0.99, "sla_sigma_x": 0.5 } @@ -468,9 +472,11 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "hidden_listing": false, "end_date": 1893456000, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' + -d '{"machine": 12345, "price_disk": 0.15, "hidden_listing": false, "end_date": "CURRENT_END_DATE_FROM_SHOW_MACHINES", "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` +Replace `CURRENT_END_DATE_FROM_SHOW_MACHINES` with the current `end_date` from `show machines`. Do not leave a far-future timestamp in a copied body. A later `end_date` extends live SLA contracts. + **Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. #### Common errors @@ -550,19 +556,22 @@ vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 - In the **You net** column, values follow host earnings sign conventions: positive means SLA fee you kept; negative means credit you owed the client. -| Measured reliability (simplified) | You net (per day) | +| Blended reliability vs the client's target | You net (per day) | | --- | --- | -| ~100% (excellent day) | +$0.20 (keep SLA fee) | -| ~99% (good day) | +$0.17 (keep most of the SLA fee) | +| Meets or exceeds the target (for example blended ~99% vs a 95% target) | +$0.20 (keep the full SLA fee) | -You keep most or all of the SLA fee. +When the blended measure meets the target, you keep the SLA fee. These rows are not raw uptime. + + +Settlement uses a **blended** reliability measure (recent plus longer-term uptime), not the day's raw uptime alone. A day whose raw uptime is at or slightly above the target can still settle with a small partial credit if the blended measure falls below it. When the blended measure meets the target, no credit is paid. + ### What if measured reliability is between the client's target and my reliability commitment? -Example: you publish **reliability commitment 99%**, the client chose **target 95%**, and measured reliability is **~97%**. +Example: you publish **reliability commitment 99%**, the client chose **target 95%**, and the **blended** measure is **~97%**. - **Credits** are evaluated against the client's **target** (95%), not your reliability commitment. -- Because 97% is above 95%, you typically **owe no SLA credit** for that day. +- Because that blended 97% is above 95%, you **owe no SLA credit** for that day. Raw uptime in the same range can still credit if the blend is below the target. - **SLA fees** are priced from your **reliability commitment**, confidence, and the client's target — a higher reliability commitment relative to the target generally means lower client charges. The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what drives service-credit eligibility. @@ -616,7 +625,7 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **Or use CLI/REST below.** Forgiveness is not guaranteed either way. -**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. The CLI does not send `maintenance_reason`; the REST body can. +**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. Include `duration` (whole hours) and `maintenance_category`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. **`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -629,11 +638,20 @@ vastai schedule maint MACHINE_ID \ --maintenance_category software ``` -REST equivalent: `PUT /api/v0/machines/{machine_id}/dnotify` with `"sdate"` as Unix epoch seconds (UTC) at least 24 hours ahead (optional `"maintenance_reason": "OS kernel upgrade"`) — see [Schedule Maintenance](/api-reference/machines/schedule-maint). +REST equivalent: + +```bash +curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ + -H "Authorization: Bearer $VAST_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"sdate": START_UNIX_UTC, "duration": 2, "maintenance_category": "software"}' +``` + +`sdate` is Unix epoch seconds (UTC), at least 24 hours ahead for planned notice. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). **Cancel or reschedule:** To cancel a window, use [`vastai cancel maint`](/host/cli/cancel-maint) (requires `machine_write`) or the [REST cancel-maintenance API](/api-reference/machines/cancel-maint). To reschedule, cancel the existing window, then run `schedule maint` with a new `--sdate` (still ≥24 hours ahead for planned SLA maintenance). -**Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice credits do not apply to unplanned outages. +**Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. See [CLI install](/cli/hello-world) if you have not set up the CLI. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 689c2d38..e30feb1d 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -33,7 +33,7 @@ vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_ca -Optional REST body field `maintenance_reason` (short description for notifications) is available on [Schedule Maintenance](/api-reference/machines/schedule-maint). The published CLI does not yet expose a `--maintenance_reason` flag. +The schedule-maintenance API currently stores `maintenance_reason` as empty, so a reason in the REST body is not shown to renters. Send `sdate`, `duration` (whole hours), and `maintenance_category`. See [Schedule Maintenance](/api-reference/machines/schedule-maint). ## Description From a4f36a153cc8fb8e8b9b57b9494c4cf00e4a9992 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:30:11 -0700 Subject: [PATCH 152/250] docs(sla): fix fleet script rate limits and backtester auth errors (lane review 2) create_asks is rate-limited at threshold 5.0, so the re-list loop now waits 5 s (and 429 is in the error table); it also skips rolling duration listings, whose end_date would otherwise be written back as a fixed date, and checks ALLOWLIST before the loop. The backtester error table now matches the pinned auth responses (403/404 auth_error), the fleet script logs to stderr so stdout stays JSONL, and beta is described as range-checked but ignored. Co-Authored-By: Claude Opus 5.5 (1M context) --- host/sla-backtester.mdx | 16 +++++++++------- host/sla-offers.mdx | 16 +++++++++++----- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 579d5d8e..9c2befd2 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -88,7 +88,7 @@ Requires Bearer authentication. Rate-limited to about one request every two seco | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | -`beta` is accepted but ignored for host accounts; the value actually used is echoed in `params.beta`. Any other unknown query parameter is rejected with `400 bad_request`. The older `r` and `reliability` parameters are no longer accepted; use `r_claim` (and `r_target`). +`beta` is not a host setting. If sent, it must be between 0 and 1 and is otherwise ignored; the value actually used is echoed in `params.beta`. Any other unknown query parameter is rejected with `400 bad_request`. The older `r` and `reliability` parameters are no longer accepted; use `r_claim` (and `r_target`). ### Limits @@ -258,10 +258,12 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** | 400 | `invalid_params` | The SLA terms don't combine, for example `r_target` greater than `r_claim` | | 400 | `invalid_range` | `start_date` is after `end_date` | | 400 | `range_too_large` | The window is longer than 366 days | -| 401 | — | Missing or invalid API key, or the key lacks `machine_read`. See [Authentication](/api-reference/authentication). | +| 401 | `auth_error` | Unknown API key, or the key lacks `machine_read`. See [Authentication](/api-reference/authentication). | +| 403 | `auth_error` | No `Authorization` header ("This action requires login.") | | 403 | `not_owner` | The machine belongs to another host | | 403 | `sla_disabled` | SLA is not currently enabled on the platform. Try again later or contact support. | | 404 | `machine_not_found` | Invalid `machine_id` | +| 404 | `auth_error` | Malformed API key (wrong length) | | 429 | — | Too many requests. Wait at least two seconds and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | ## Recommended workflow @@ -298,7 +300,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do r=$(echo "$machine" | jq -r '(.sla_reliability_claim // 0) | if . > 0 then . else empty end') if [ -z "$r" ] && [ -n "${R:-}" ]; then r="$R"; echo "machine $id: using fallback R=$R" >&2; fi if ! jq -e -n --arg r "$r" 'try (($r | tonumber) > 0) catch false' >/dev/null 2>&1; then - echo "skip $id: no SLA terms visible; set R=0.99 (or your planned commitment) as a fallback"; continue + echo "skip $id: no SLA terms visible; set R=0.99 (or your planned commitment) as a fallback" >&2; continue fi # show machines returns confidence as a label: high = Tight, medium = Normal, low = Wide. # P only fills in for machines without SLA terms. @@ -310,14 +312,14 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do [ -n "$p" ] && echo "machine $id: using fallback P=$P (sla_confidence null)" >&2 ;; esac if [ -z "$p" ]; then - echo "skip $id: no sla_confidence; set P=0.6667 (Normal) to backtest before enabling SLA"; continue + echo "skip $id: no sla_confidence; set P=0.6667 (Normal) to backtest before enabling SLA" >&2; continue fi out="$BT_DIR/sla_bt_$id.json" http=$(curl -s -o "$out" -w "%{http_code}" \ -H "Authorization: Bearer $VAST_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r_claim=$r&p=$p") if [ "$http" != "200" ] || ! jq -e '.success == true' "$out" >/dev/null 2>&1; then - echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' "$out" 2>/dev/null)" + echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' "$out" 2>/dev/null)" >&2 sleep 3; continue fi jq -c --arg id "$id" '{machine_id: $id, params, has_data, r_eff, r_be, @@ -329,14 +331,14 @@ done Expect about three seconds per machine (`sleep 3` plus request time), so budget a few minutes for 50 machines. The example logs a failure and moves on after one attempt. On HTTP **429**, wait and retry that machine before treating it as failed. Don't run requests in parallel unless you implement backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). -3. Compare `r_eff`, `r_be`, `net_sla`, and `largest_day_credit` across machines. +3. Compare `r_eff`, `r_be`, `net_sla`, and `largest_day_credit` across machines. Skip and failure messages go to stderr, so stdout is one JSON object per machine. Save the script as `bt.sh` and sort the results: `./bt.sh > results.jsonl && jq -s 'sort_by(.net_sla)' results.jsonl`. 4. Apply matching `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). ## When stuck - **`has_data: false`** — Widen the date range or wait for rental history. - **`400 bad_request` on a request that used to work** — Replace `r=` with `r_claim=` and remove `reliability=`. -- **`401`** — Check API key permissions (`machine_read`) and the Bearer header format. +- **`401` / `403 auth_error` / `404 auth_error`** — Check that the `Authorization: Bearer` header is present, the key is complete (64 characters), and it has `machine_read`. - **Still stuck** — Ask in the [host Discord](https://discord.gg/hSuEbSQ4X8). ## Related documentation diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 0e2c3464..66286e07 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -382,7 +382,7 @@ For multiple machines, loop sequentially — do not parallelize without backoff: 1. Skip machines missing base pricing fields. 2. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields (preserve existing reliability commitment and confidence when set). -3. Space requests (`sleep 2` in the example). At fleet scale, detect HTTP **429** and retry that machine with backoff before treating it as failed—do not rerun the whole loop with `DRY_RUN=0` until transient rate limits clear. +3. Space requests at least 5 seconds apart (`sleep 5` in the example; `create_asks` has an `x-rate-limit` threshold of `5.0`). At fleet scale, detect HTTP **429** and retry that machine with backoff before treating it as failed—do not rerun the whole loop with `DRY_RUN=0` until transient rate limits clear. 4. On `invalid_sla_params`, `sla_not_approved`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. @@ -399,11 +399,11 @@ ALLOWLIST="${ALLOWLIST:-}" # makes the listing public. Put every hidden machine ID here, or leave it off ALLOWLIST. HIDDEN_IDS="${HIDDEN_IDS:-}" DRY_RUN="${DRY_RUN:-1}" +if [ "$DRY_RUN" = "0" ] && [ -z "$ALLOWLIST" ]; then + echo "abort: set ALLOWLIST to Listed machine IDs before DRY_RUN=0" >&2; exit 1 +fi machines=$(vastai show machines --raw) for id in $(echo "$machines" | jq -r '.machines[].id'); do - if [ "$DRY_RUN" = "0" ] && [ -z "$ALLOWLIST" ]; then - echo "abort: set ALLOWLIST to Listed machine IDs before DRY_RUN=0"; break - fi if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then echo "skip $id: not in ALLOWLIST"; continue fi @@ -412,6 +412,11 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if ! echo "$machine" | jq -e '.listed == true' >/dev/null; then echo "skip $id: not listed (this loop never republishes unlisted machines)"; continue fi + # Rolling listings (-l / duration) recompute end_date daily; writing end_date back would + # turn them into a fixed end date. Republish those from the console instead. + if echo "$machine" | jq -e '.duration != null' >/dev/null; then + echo "skip $id: rolling duration listing (republish from the console)"; continue + fi price=$(echo "$machine" | jq -r '.listed_gpu_cost // empty') end=$(echo "$machine" | jq -r '.end_date // empty') chunk=$(echo "$machine" | jq -r '.listed_min_gpu_count // empty') @@ -457,7 +462,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do else echo "machine_id=$id error: $(echo "$resp" | jq -c '{success,error,msg}' 2>/dev/null || echo "$resp")" fi - sleep 2 + sleep 5 done ``` @@ -489,6 +494,7 @@ Replace `CURRENT_END_DATE_FROM_SHOW_MACHINES` with the current `end_date` from ` | 403 | `sla_daemon_outdated` | Machine daemon build is too old for SLA listing | | 400 | `invalid_args` | Machine ID not found for your account, or malformed / incompatible request body | | 400 | `invalid_sla_params` | SLA parameters failed validation | +| 429 | *(rate limited)* | Too many requests. Space fleet calls at least 5 seconds apart, then retry the machines that failed | | 402 | `msg`: `can only create asks for an online machine` | The daemon has not checked in for more than 60 seconds. Wait until **Host → Machines** shows the machine online, then retry. If the machine is down, use `vastai unlist machine MACHINE_ID` instead. | **`machine_locked`:** Returned when a machine is decommissioned or migration-locked. If you are migrating hardware, finish or cancel active rentals first, remove or update the listing as needed, and contact support if the machine remains locked. Existing SLA terms on active contracts remain in force until those contracts end. From f0ef7601d331d0ebae560de420bf15ab4faf85bc Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:33:53 -0700 Subject: [PATCH 153/250] docs(sla): address doc-review consensus (cycle 101) State per-contract SLA exposure, and match listing and rent status codes to the API. Co-authored-by: Cursor --- api-reference/openapi.yaml | 81 +++++++++---------- .../openapi/yaml/create_instance.yaml | 28 ++----- api-reference/openapi/yaml/list_machine.yaml | 14 ++-- guides/instances/choosing/sla-coverage.mdx | 4 +- host/sla-offers.mdx | 34 ++++---- snippets/host/cli/schedule-maint.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 2 +- 7 files changed, 74 insertions(+), 91 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 2401bcd4..6c064cd5 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1809,8 +1809,11 @@ paths: '400': description: "Bad Request. SLA failures use `invalid_sla_params` (no SLA\ \ on the offer, target above the host commitment, target out of range,\ - \ or SLA fee above 1\xD7 compute). Also SSH key requirements and `no_such_ask`\ - \ when the offer is gone.\n" + \ or SLA fee above 1\xD7 compute). Also SSH key requirements. A missing\ + \ offer is HTTP 400 `invalid_args` with `no_such_ask` (`msg` contains\ + \ `error 404/3603`). A host account renting someone else's offer is also\ + \ HTTP 400 `invalid_args` (`msg` contains `error 403/3586`). The HTTP\ + \ status is 400 in both cases.\n" content: application/json: schema: @@ -1840,27 +1843,11 @@ paths: schema: $ref: '#/components/schemas/Error' '403': - description: Forbidden - content: - application/json: - schema: - type: object - properties: - success: - type: boolean - example: false - error: - type: string - example: invalid_args - msg: - type: string - example: 'error 403/3586: Offer 1234567 is not your own. Hosts - can only rent their own machines.' - ask_id: - type: integer - example: 1234567 - '404': - description: Offer not found or not available + description: 'Forbidden. SLA is not enabled for this account or region (`error` + is `sla_disabled`). A host account renting another host''s offer is not + 403; that is HTTP 400 with `error 403/3586` inside `msg`. + + ' content: application/json: schema: @@ -1871,11 +1858,10 @@ paths: example: false error: type: string - example: invalid_args + example: sla_disabled msg: type: string - example: 'error 404/3603: no_such_ask Instance type by id 1234567 - is not available.' + example: SLA is not enabled. ask_id: type: integer example: 1234567 @@ -4520,17 +4506,18 @@ paths: \ rent on the vast.ai platform.\nAllows setting offer pricing, rental types,\ \ end dates, discount rates, and SLA parameters.\nUnspecified fields generally\ \ keep their current values, except `price_disk` (defaults to 0.10), `duration`\ - \ (cleared if omitted) and `hidden_listing` (defaults to false). Send `price_disk`\ - \ and `hidden_listing` on every update. Send either `duration` or `end_date`,\ - \ never both (400). Read the current offer with show machines before changing\ - \ pricing.\n\nSLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional\ - \ `sla_max_beta`) are supported on this REST endpoint. SLA activates when\ - \ `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are\ - \ ignored \u2014 clients choose a reliability target at search/rent time.\ - \ The published CLI and SDK do not yet expose SLA fields \u2014 use the host\ - \ console (**Set Pricing \u2192 SLA**) or REST/`curl` until CLI/SDK support\ - \ ships.\n\nCLI Usage (non-SLA fields): `vastai list machine \ - \ [options]`" + \ (cleared if omitted), `hidden_listing` (defaults to false), and `min_chunk`\ + \ (defaults to 1). Omitting `vol_size` on a machine with no volume offer creates\ + \ one at half the free disk; send `0` to opt out. Send `price_disk`, `hidden_listing`,\ + \ and `min_chunk` on every update. Send either `duration` or `end_date`, never\ + \ both (400). Read the current offer with show machines before changing pricing.\n\ + \nSLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`)\ + \ are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`.\ + \ Host-sent `sla_r_target` / legacy `sla_reliability` are ignored \u2014 clients\ + \ choose a reliability target at search/rent time. The published CLI and SDK\ + \ do not yet expose SLA fields \u2014 use the host console (**Set Pricing\ + \ \u2192 SLA**) or REST/`curl` until CLI/SDK support ships.\n\nCLI Usage (non-SLA\ + \ fields): `vastai list machine [options]`" security: - BearerAuth: [] requestBody: @@ -4567,7 +4554,10 @@ paths: description: Minimum bid price allowed min_chunk: type: integer - description: Minimum number of GPUs that must be rented together + description: Minimum number of GPUs that must be rented together. + Omitted values reset to 1, which can slice a machine that was + previously whole-GPU only. Send the current listed_min_gpu_count + on every update. default: 1 end_date: type: number @@ -4576,11 +4566,13 @@ paths: send together with `duration` (400 Cannot set both duration and end_date). duration: - type: number - format: float - description: Auto-renew length in seconds. Send this instead of - `end_date` for listings created with `vastai list machine -l`. - Omitting it on an auto-renew listing turns auto-renew off. + type: integer + description: 'Whole seconds until the listing ends (auto-renewing + listings). Floats such as 2592000.0 are rejected with 400 Invalid + duration. Mutually exclusive with end_date. Omitting it on an + auto-renew listing turns auto-renew off. + + ' hidden_listing: type: boolean description: When true, the offer is not shown in search. Defaults @@ -4609,7 +4601,8 @@ paths: format: float description: "Host confidence spread \u2014 how wide your belief\ \ is around the claim.\nMust be greater than 0 and at most 3.0.\ - \ Defaults to 0.5 when enabling SLA.\n" + \ Defaults to 0.5 when SLA is first enabled on an ask. Omitting\ + \ it on an existing SLA ask keeps the current value.\n" sla_max_beta: type: number format: float diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index ab41040b..c2daed69 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -199,7 +199,7 @@ paths: example: 1234568 '400': description: | - Bad Request. SLA failures use `invalid_sla_params` (no SLA on the offer, target above the host commitment, target out of range, or SLA fee above 1× compute). Also SSH key requirements and `no_such_ask` when the offer is gone. + Bad Request. SLA failures use `invalid_sla_params` (no SLA on the offer, target above the host commitment, target out of range, or SLA fee above 1× compute). Also SSH key requirements. A missing offer is HTTP 400 `invalid_args` with `no_such_ask` (`msg` contains `error 404/3603`). A host account renting someone else's offer is also HTTP 400 `invalid_args` (`msg` contains `error 403/3586`). The HTTP status is 400 in both cases. content: application/json: schema: @@ -228,26 +228,8 @@ paths: schema: $ref: '#/components/schemas/Error' '403': - description: Forbidden - content: - application/json: - schema: - type: object - properties: - success: - type: boolean - example: false - error: - type: string - example: invalid_args - msg: - type: string - example: "error 403/3586: Offer 1234567 is not your own. Hosts can only rent their own machines." - ask_id: - type: integer - example: 1234567 - '404': - description: Offer not found or not available + description: | + Forbidden. SLA is not enabled for this account or region (`error` is `sla_disabled`). A host account renting another host's offer is not 403; that is HTTP 400 with `error 403/3586` inside `msg`. content: application/json: schema: @@ -258,10 +240,10 @@ paths: example: false error: type: string - example: invalid_args + example: sla_disabled msg: type: string - example: "error 404/3603: no_such_ask Instance type by id 1234567 is not available." + example: "SLA is not enabled." ask_id: type: integer example: 1234567 diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 4426abe6..50247e16 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -13,7 +13,7 @@ paths: description: | Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. - Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted) and `hidden_listing` (defaults to false). Send `price_disk` and `hidden_listing` on every update. Send either `duration` or `end_date`, never both (400). Read the current offer with show machines before changing pricing. + Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted), `hidden_listing` (defaults to false), and `min_chunk` (defaults to 1). Omitting `vol_size` on a machine with no volume offer creates one at half the free disk; send `0` to opt out. Send `price_disk`, `hidden_listing`, and `min_chunk` on every update. Send either `duration` or `end_date`, never both (400). Read the current offer with show machines before changing pricing. SLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are ignored — clients choose a reliability target at search/rent time. The published CLI and SDK do not yet expose SLA fields — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. @@ -54,16 +54,18 @@ paths: description: Minimum bid price allowed min_chunk: type: integer - description: Minimum number of GPUs that must be rented together + description: Minimum number of GPUs that must be rented together. Omitted values reset to 1, which can slice a machine that was previously whole-GPU only. Send the current listed_min_gpu_count on every update. default: 1 end_date: type: number format: float description: Unix timestamp for when the listing expires. Do not send together with `duration` (400 Cannot set both duration and end_date). duration: - type: number - format: float - description: Auto-renew length in seconds. Send this instead of `end_date` for listings created with `vastai list machine -l`. Omitting it on an auto-renew listing turns auto-renew off. + type: integer + description: > + Whole seconds until the listing ends (auto-renewing listings). Floats such as + 2592000.0 are rejected with 400 Invalid duration. Mutually exclusive with end_date. + Omitting it on an auto-renew listing turns auto-renew off. hidden_listing: type: boolean description: When true, the offer is not shown in search. Defaults to false if omitted, which makes a hidden listing public. `show machines` does not return this flag. @@ -85,7 +87,7 @@ paths: format: float description: | Host confidence spread — how wide your belief is around the claim. - Must be greater than 0 and at most 3.0. Defaults to 0.5 when enabling SLA. + Must be greater than 0 and at most 3.0. Defaults to 0.5 when SLA is first enabled on an ask. Omitting it on an existing SLA ask keeps the current value. sla_max_beta: type: number format: float diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 8503d461..7b6692a6 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -288,7 +288,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | --- | --- | --- | | Offer has no SLA, target is above the host commitment, target is out of range, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | | SLA not enabled for the account or region | HTTP 403 `sla_disabled` | Contact support | -| Offer no longer exists | HTTP 400 `invalid_args` / `no_such_ask`, HTTP 404, or HTTP 410 | Re-search and use a fresh offer ID | +| Offer no longer exists | HTTP 400 `invalid_args` (`no_such_ask`; `msg` may contain `error 404/3603`) or HTTP 410 | Re-search and use a fresh offer ID. The HTTP status for a missing offer is 400, not 404. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | Before sending the same `PUT` again, check `GET /api/v1/instances/` for a new contract. There is no idempotency key, so a blind retry can create a second paid rental. | @@ -347,7 +347,7 @@ Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host re | Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (net credit after SLA fee) | | Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | -**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without the SLA. Credits are graduated. A day close to your target can pay a small credit, and the further below target the day falls, the larger the credit. A day that meets the target does not pay a credit. +**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without the SLA. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day that meets the target does not pay a credit. Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 66286e07..e2c0396e 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -148,7 +148,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | | Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.99999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | -| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA fees for clients at a given target). Defaults to `0.5` if omitted. | +| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA fees for clients at a given target). Defaults to `0.5` when SLA is first enabled on an ask. On an existing SLA ask, omitting `sla_sigma_x` keeps the current value. | ### Advanced: `sla_max_beta` (optional) @@ -200,7 +200,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.99999**. Exactly `1.0` is rejected. -- When the reliability commitment is positive, `sla_sigma_x` must be positive and at most `3.0` (defaults to `0.5` if omitted). +- When the reliability commitment is positive, `sla_sigma_x` must be positive and at most `3.0`. It defaults to `0.5` when SLA is first enabled. On an existing SLA ask, omitting it keeps the current value. - Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. @@ -213,7 +213,9 @@ SLA settlement applies per rental contract. If your machine has multiple GPU sli The backtester replays **machine-level** daily earnings (total compute across all active rentals on that machine). Its largest single-day credit reflects the worst simulated day for the whole machine in the replay window — not a single GPU slice in isolation. -If multiple on-demand SLA contracts can be active on one machine at once, a single outage may trigger service credits **per contract**. The backtester’s largest single-day credit reflects a machine-level replay as one contract—it may not equal the sum of worst-case credits across concurrent SLA renters. For sliced hosts, treat it as a **lower bound** until you confirm aggregation with support. Do **not** naively multiply it by contract count as a substitute for that check—the backtester already models machine-level compute for the replay window, but live per-contract settlement can still stack differently than one simulated day. +The backtester simulates **one** SLA contract. On a sliced machine, each concurrently rented SLA contract settles separately, so real single-day credits can be higher than that simulated day. + +For planning, assume a worst-case day costs up to one full day of covered compute for **each** SLA contract running on the machine that day, plus any closing settlement on a contract's last active day (see [Simulation limits](/host/sla-backtester#simulation-limits)). Ask support if you want a tighter estimate before listing tight SLA terms on sliced machines. ### SLA on extended contracts @@ -278,10 +280,10 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "hidden_listing": false, "end_date": "CURRENT_END_DATE_FROM_SHOW_MACHINES", "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `end_date` with the machine's **current** `end_date` from `show machines` (a Unix timestamp, not the placeholder string). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. +Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_END_DATE_UNIX` with the machine's current `end_date` from `show machines`, as a number with no quotes. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (omitting `min_chunk` resets it to 1). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. Send your **current** `end_date` unless you intend to extend. A later `end_date` at the same or lower price extends existing rental contracts, including their SLA terms and service-credit exposure. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). @@ -299,10 +301,11 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ "machine": 12345, "price_gpu": 3.50, "price_disk": 0.15, + "min_chunk": CURRENT_MIN_CHUNK, "hidden_listing": false, "sla_r_claim": 0.99, "sla_sigma_x": 0.5, - "end_date": "CURRENT_END_DATE_FROM_SHOW_MACHINES" + "end_date": CURRENT_END_DATE_UNIX }' ``` @@ -317,8 +320,9 @@ SLA fields example (existing listing, same limit as the curl above): "machine": 12345, "price_gpu": 3.50, "price_disk": 0.15, + "min_chunk": CURRENT_MIN_CHUNK, "hidden_listing": false, - "end_date": "CURRENT_END_DATE_FROM_SHOW_MACHINES", + "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.99, "sla_sigma_x": 0.5 } @@ -333,7 +337,9 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - `price_disk` resets to **$0.10/GB/month** if omitted or `null`. - `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing). - `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. -- Send **either** `duration` (when `show machines` returns a non-null `duration`) **or** `end_date`, never both. Both together returns `400` `Cannot set both duration and end_date`. +- `min_chunk` resets to **1** if omitted, which can make a whole-GPU listing sliceable. Send the current `listed_min_gpu_count`. +- `vol_size` omitted on a machine with no volume offer creates one sized at half the free disk. Send `"vol_size": 0` to keep volume offers off. +- Send **either** `duration` (integer seconds; a float such as `2592000.0` returns 400 `Invalid duration`) **or** `end_date`, never both. Sending both returns `400` `Cannot set both duration and end_date`. Always read the current listing and send `price_disk` plus either `duration` or `end_date`. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. @@ -477,10 +483,10 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "hidden_listing": false, "end_date": "CURRENT_END_DATE_FROM_SHOW_MACHINES", "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' + -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` -Replace `CURRENT_END_DATE_FROM_SHOW_MACHINES` with the current `end_date` from `show machines`. Do not leave a far-future timestamp in a copied body. A later `end_date` extends live SLA contracts. +Replace `CURRENT_END_DATE_UNIX` and `CURRENT_MIN_CHUNK` with the current values from `show machines`, as numbers with no quotes. A later `end_date` extends live SLA contracts. Omitting `min_chunk` resets it to 1. **Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. @@ -588,16 +594,16 @@ The **reliability commitment** is your belief and pricing knob. The client's **r Credits scale relative to the day's compute, not only the SLA fee collected. A single bad day near the client's target boundary can cost as much as 200+ days of collected SLA fees. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. -These scenarios show settlement when reliability **drops to or below** a 95% client target — they are boundary illustrations, not typical strong days: +These scenarios show settlement when the blended measure falls **below** a 95% client target. They are illustrations, not typical strong days: | Measured reliability (simplified) | You net (per day) | | --- | --- | -| Just below target on the blended measure (daily uptime may look close to 95%) | −$42 (credit you owe) | +| Blended measure ~93–94% (illustrative shortfall) | −$42 (credit you owe) | | Well below target (~90% or less) | −$84 (large credit owed) | To put the asymmetry in perspective: at ~$0.20/day in SLA fees, it takes roughly 210 strong days to accumulate the $42 you could lose on a single day at the target boundary. The SLA fee is a small fraction of daily compute, while credits scale against total daily compute. -Your maximum SLA loss on any single settlement day is bounded by that day's covered compute (GPU, storage, and bandwidth). +Your maximum SLA loss on any single settlement day is bounded by that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). The closing settlement on a contract's last day can add more. ## Risk scenarios @@ -626,7 +632,7 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **Console** 1. Open [Host → Machines](https://cloud.vast.ai/host/machines/), then **Settings** → **Machine Maintenances**. -2. Set a start at least 24 hours ahead and a duration in whole hours. +2. Set a start at least 24 hours ahead and a duration in whole hours. The server rounds a fractional duration **down** (minimum 1 hour), so `2.5` becomes a 2-hour window. Round **up** when sizing an SLA maintenance window. 3. Confirm the window is listed in that table before you take the machine down. **Or use CLI/REST below.** Forgiveness is not guaranteed either way. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index e30feb1d..f1f7b582 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -25,7 +25,7 @@ vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_ca - Maintenance duration in hours. Prefer whole hours for REST compatibility (OpenAPI `duration` is an integer). The CLI may accept fractional values (for example `0.5`). + Maintenance duration in whole hours. The server rounds fractional values **down** (minimum 1 hour), so `2.5` is stored as 2 hours. Round **up** when sizing an SLA maintenance window. diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index e09dbe81..05bc031b 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `end_date` is on this method and on that REST call. Volume size, volume price, and duration flags (`-v`, `-z`, `-l` on the CLI) are CLI-only today. Do not send `vol_size` or `vol_price` on that REST call. Follow the read → merge → PUT rule in [Offering SLA](/host/sla-offers): send back `price_disk`, `hidden_listing` when the listing is hidden, and either `duration` (auto-renew) or `end_date`. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `end_date` is on this method and on that REST call. `duration`, `vol_size`, and `vol_price` are REST body fields; the CLI flags `-l`, `-v`, and `-z` send them. If you previously opted out of volume offers, send `"vol_size": 0` on every update, or a volume offer is created when none exists. Follow the read → merge → PUT rule in [Offering SLA](/host/sla-offers): send back `price_disk`, `hidden_listing` when the listing is hidden, and either `duration` (auto-renew) or `end_date`. ## Signature From eefa991a9e4e885caf83bdc6e23786b326ffe919 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:36:35 -0700 Subject: [PATCH 154/250] docs(sla): reconcile fleet loop duration handling and script hygiene (lane review 3) Drop the rolling-listing skip: the loop already sends an integer duration for rolling listings (the backend keeps them rolling), and the skip made that branch dead and contradicted the prose. Fleet scripts no longer overwrite VAST_API_KEY with a placeholder, the backtest loop ignores stale confidence labels when it falls back to R, the run line passes R/P through, and the lookback limit states the 91 inclusive rows. Co-Authored-By: Claude Opus 5.5 (1M context) --- host/sla-backtester.mdx | 16 ++++++++++------ host/sla-offers.mdx | 7 +------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 9c2befd2..a450c5e1 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -94,7 +94,7 @@ Requires Bearer authentication. Rate-limited to about one request every two seco | Limit | Value | | --- | --- | -| Default lookback | 90 days | +| Default lookback | 90 days before `end_date` (91 inclusive UTC-day rows; today's row is usually empty) | | Maximum range | 366 days (inclusive) | | Ownership | Must own the machine | | Rate limit | About one request every two seconds | @@ -214,7 +214,7 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ ``` - **`net_sla`** — SLA fees minus service credits over the window. Positive means SLA would have added income. -- **`largest_day_credit`** — the most credit paid out on any single day. Use it as your single-day tail-risk reference (the last active day can be larger because it includes the closing settlement). +- **`largest_day_credit`** — the most credit paid out on any single day. Use it as your single-day tail-risk reference. The largest value often falls on the last active day, because that day includes the contract's closing settlement. ## Interpreting results @@ -288,7 +288,7 @@ Optional, for API automation only. To check one machine, use the single-machine 2. Responses are written to a private temp directory that is deleted when the loop exits. ```bash -export VAST_API_KEY="YOUR_API_KEY" +: "${VAST_API_KEY:?export VAST_API_KEY first (needs machine_read)}" # Optional fallbacks for machines without SLA yet (machines with SLA keep their own terms): R=0.99 P=0.6667 BT_DIR=$(mktemp -d) trap 'rm -rf "$BT_DIR"' EXIT @@ -298,13 +298,17 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do '.machines[] | select((.id|tostring) == $id)') # Treat 0 (SLA off) and null (terms hidden) as absent; R only fills in for those machines. r=$(echo "$machine" | jq -r '(.sla_reliability_claim // 0) | if . > 0 then . else empty end') - if [ -z "$r" ] && [ -n "${R:-}" ]; then r="$R"; echo "machine $id: using fallback R=$R" >&2; fi + used_r_fallback=0 + if [ -z "$r" ] && [ -n "${R:-}" ]; then r="$R"; used_r_fallback=1; echo "machine $id: using fallback R=$R" >&2; fi if ! jq -e -n --arg r "$r" 'try (($r | tonumber) > 0) catch false' >/dev/null 2>&1; then echo "skip $id: no SLA terms visible; set R=0.99 (or your planned commitment) as a fallback" >&2; continue fi # show machines returns confidence as a label: high = Tight, medium = Normal, low = Wide. # P only fills in for machines without SLA terms. - case "$(echo "$machine" | jq -r '.sla_confidence // empty')" in + # When R was used, the machine's SLA terms are off or hidden, so any confidence label is stale: use P. + label=$(echo "$machine" | jq -r '.sla_confidence // empty') + [ "$used_r_fallback" = 1 ] && label="" + case "$label" in high) p=0.83 ;; medium) p=0.6667 ;; low) p=0.50 ;; @@ -331,7 +335,7 @@ done Expect about three seconds per machine (`sleep 3` plus request time), so budget a few minutes for 50 machines. The example logs a failure and moves on after one attempt. On HTTP **429**, wait and retry that machine before treating it as failed. Don't run requests in parallel unless you implement backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). -3. Compare `r_eff`, `r_be`, `net_sla`, and `largest_day_credit` across machines. Skip and failure messages go to stderr, so stdout is one JSON object per machine. Save the script as `bt.sh` and sort the results: `./bt.sh > results.jsonl && jq -s 'sort_by(.net_sla)' results.jsonl`. +3. Compare `r_eff`, `r_be`, `net_sla`, and `largest_day_credit` across machines. Skip and failure messages go to stderr, so stdout is one JSON object per machine. Save the script as `bt.sh`, pass any fallbacks on the same line, and sort the results: `R=0.99 P=0.6667 ./bt.sh > results.jsonl && jq -s 'sort_by(.net_sla)' results.jsonl`. 4. Apply matching `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). ## When stuck diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e2c0396e..2c48cad2 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -396,7 +396,7 @@ See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for This example is illustrative: it sleeps between machines and logs success/error from JSON, but does not implement full HTTP 429 retry. Add status checks and backoff before production fleet rollouts. ```bash -export VAST_API_KEY="YOUR_API_KEY" +: "${VAST_API_KEY:?export VAST_API_KEY first (needs machine_write and machine_read)}" # Leave DRY_RUN=1 until you confirm each machine is **Listed** (or on your allowlist). # Set DRY_RUN=0 to apply. # ALLOWLIST required for DRY_RUN=0 (space-separated listed machine IDs). @@ -418,11 +418,6 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if ! echo "$machine" | jq -e '.listed == true' >/dev/null; then echo "skip $id: not listed (this loop never republishes unlisted machines)"; continue fi - # Rolling listings (-l / duration) recompute end_date daily; writing end_date back would - # turn them into a fixed end date. Republish those from the console instead. - if echo "$machine" | jq -e '.duration != null' >/dev/null; then - echo "skip $id: rolling duration listing (republish from the console)"; continue - fi price=$(echo "$machine" | jq -r '.listed_gpu_cost // empty') end=$(echo "$machine" | jq -r '.end_date // empty') chunk=$(echo "$machine" | jq -r '.listed_min_gpu_count // empty') From d2516788d29e0376c8f67cc00a1abb7cd890a56a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:41:29 -0700 Subject: [PATCH 155/250] docs(sla): address doc-review consensus (cycle 102) Keep fleet updates from creating volume offers, and match extension and rent error codes to the API. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 8 +++--- guides/instances/choosing/sla-coverage.mdx | 5 ++-- host/sla-offers.mdx | 33 ++++++++++++++-------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 577ce84a..796f0084 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -75,7 +75,7 @@ Filter examples (including SLA quotes) are under [Examples](#examples). Query sy ## Examples -**The console and REST quote SLA pricing. The CLI can find SLA offers but cannot price them.** Prefer `dph_total` (and `--order dph_total`) only after a console or REST search that set `target_reliability`. Match `--storage` to `--disk` if you rent via CLI for non-SLA. To **enable** SLA at rent, see [Next step for SLA](#next-step-for-sla) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +The CLI can find SLA offers but cannot price them. Treat `dph_total` as SLA-inclusive only when the search set `target_reliability` in the console or REST. From the CLI, `--order dph_total` sorts by price without the SLA fee. Match `--storage` to `--disk` if you rent via CLI for non-SLA. To **enable** SLA at rent, see [Next step for SLA](#next-step-for-sla) and [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash @@ -83,13 +83,13 @@ Filter examples (including SLA quotes) are under [Examples](#examples). Query sy # rented=false (excludes slots you already rent) is already in the CLI default query; shown here explicitly vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=false' -# Find SLA offers (the CLI cannot quote the SLA fee today; see the Warning below) +# Find SLA offers. dph_total here excludes the SLA fee (see the Warning below). # Always set --storage explicitly when comparing dph_total (CLI default 5 GiB ≠ REST 8 GB). vastai search offers 'has_sla=true expected_reliability>=0.99' --storage 50 --order dph_total ``` -The current CLI cannot quote an SLA fee: it sends `target_reliability=0.95` as `{"eq": 0.95}`, which search rejects with `400 target_reliability: Input should be a valid number`. Use the CLI to find SLA offers (`has_sla`, `expected_reliability`), then get the SLA-inclusive `dph_total` from the console or REST (`"target_reliability": 0.95` as a plain number). +The CLI can find SLA offers (`has_sla`, `expected_reliability`) but cannot price them. `vastai search offers 'target_reliability=0.95'` is sent as `{"eq": 0.95}` and fails with HTTP 400 (`target_reliability: Input should be a valid number`). Treat `dph_total` as SLA-inclusive only when the search set `target_reliability` in the console or REST. From the CLI, `--order dph_total` sorts by price without the SLA fee. @@ -177,7 +177,7 @@ bool = True | False | `reliability` | float | machine reliability score (see FAQ for explanation) | | `expected_reliability` | float | host’s advertised SLA reliability commitment on the offer | | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | -| `target_reliability` | float | reliability target greater than 0 and less than 1 (e.g. `0.95` = 95% — console **Reliability target**); prices `dph_total` in search only — see [SLA](/guides/instances/choosing/sla-coverage#finding-sla-offers) to enable the SLA at rent | +| `target_reliability` | float | REST and console only. The current CLI sends this as an operator object and search rejects it (HTTP 400). See the Warning under Examples. | | `rentable` | bool | is the instance currently rentable | | `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | | `storage_cost` | float | storage cost in $/GB/month | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 7b6692a6..ae423a07 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -17,7 +17,7 @@ An SLA is an optional reliability promise on an **on-demand** GPU rental. You do 3. You pay an **SLA fee** (a service level fee) on top of the GPU price. 4. Each day, Vast checks how long your instance was actually up. 5. If the blended measure met your reliability target, the host keeps the SLA fee. "Met" uses Vast's blended reliability measure (recent and longer-term uptime), not that day's raw uptime alone. A day whose raw uptime is at or slightly above your target can still produce a partial credit if the blended measure falls below it. -6. If uptime missed your reliability target, you receive a **service credit**. That credit can be larger than the SLA fee you paid that day. +6. If the blended measure fell below your reliability target, you receive a **service credit**. That credit can be larger than the SLA fee you paid that day. A few things people mix up: @@ -286,7 +286,8 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Symptom | Typical response | What to do | | --- | --- | --- | -| Offer has no SLA, target is above the host commitment, target is out of range, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | +| Target out of range (below 0 or 1 or above) | HTTP 400 `invalid_args` ("target reliability must be greater than or equal to 0 and less than 1") | Send a plain number in `[0, 1)`. | +| Offer has no SLA, target is above the host commitment, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | | SLA not enabled for the account or region | HTTP 403 `sla_disabled` | Contact support | | Offer no longer exists | HTTP 400 `invalid_args` (`no_such_ask`; `msg` may contain `error 404/3603`) or HTTP 410 | Re-search and use a fresh offer ID. The HTTP status for a missing offer is 400, not 404. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 2c48cad2..8f47d7b7 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -89,7 +89,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. 6. If the blended measure met their reliability target, you keep the SLA fee. "Met" uses Vast's blended reliability measure (recent and longer-term uptime), not that day's raw uptime alone. A day whose raw uptime is at or slightly above the target can still produce a partial credit if the blended measure falls below it. When the blended measure meets the target, no credit is paid. -7. If uptime missed their reliability target, the renter receives a **service credit** from your earnings. One bad day can cost more than many days of fees. +7. If the blended measure fell below their reliability target, the renter receives a **service credit** from your earnings. One bad day can cost more than many days of fees. What this is not: @@ -219,7 +219,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. If the same request would raise the SLA fee on an existing SLA contract (lower commitment, wider confidence, or `sla_r_claim` set to `0`), that contract is not extended, and the response does not say so. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -276,11 +276,14 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons **Not a first listing.** Use this SLA-only body when the machine already has base pricing. For a **first publish**, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include at least `min_chunk`, disk/bandwidth prices, and `end_date`) or **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). +Omitted fields reset. Read the warning under [Full listing update](#full-listing-update-existing-ask) before you copy a body. `"vol_size": 0` keeps a new volume offer from being created. It does not delete a volume offer you already have. + ```bash +# "vol_size": 0 keeps volume offers off. Remove it only if this machine should have a volume offer. curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_END_DATE_UNIX` with the machine's current `end_date` from `show machines`, as a number with no quotes. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (omitting `min_chunk` resets it to 1). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. @@ -302,6 +305,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ "price_gpu": 3.50, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, + "vol_size": 0, "hidden_listing": false, "sla_r_claim": 0.99, "sla_sigma_x": 0.5, @@ -321,6 +325,7 @@ SLA fields example (existing listing, same limit as the curl above): "price_gpu": 3.50, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, + "vol_size": 0, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.99, @@ -338,7 +343,7 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing). - `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. - `min_chunk` resets to **1** if omitted, which can make a whole-GPU listing sliceable. Send the current `listed_min_gpu_count`. -- `vol_size` omitted on a machine with no volume offer creates one sized at half the free disk. Send `"vol_size": 0` to keep volume offers off. +- `vol_size` omitted on a machine with no volume offer creates one sized at half the free disk. Send `"vol_size": 0` to keep that from happening. `0` does not delete a volume offer that already exists. - Send **either** `duration` (integer seconds; a float such as `2592000.0` returns 400 `Invalid duration`) **or** `end_date`, never both. Sending both returns `400` `Cannot set both duration and end_date`. Always read the current listing and send `price_disk` plus either `duration` or `end_date`. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. @@ -404,6 +409,9 @@ ALLOWLIST="${ALLOWLIST:-}" # Hidden listings: show machines does not return hidden_listing, and omitting it # makes the listing public. Put every hidden machine ID here, or leave it off ALLOWLIST. HIDDEN_IDS="${HIDDEN_IDS:-}" +# Volume offers: 0 = do not create a volume offer (default). It does not delete one you already have. +# Set VOL_SIZE="" only if every allowlisted machine should get the server default (half of free disk). +VOL_SIZE="${VOL_SIZE:-0}" DRY_RUN="${DRY_RUN:-1}" if [ "$DRY_RUN" = "0" ] && [ -z "$ALLOWLIST" ]; then echo "abort: set ALLOWLIST to Listed machine IDs before DRY_RUN=0" >&2; exit 1 @@ -443,13 +451,15 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. # price_disk is required: null or omitted resets storage price to 0.10. - # Send duration OR end_date, never both (400). duration must be an integer; - # show machines returns a float, which the API rejects. hidden_listing must be explicit. - body=$(echo "$machine" | jq -c --argjson hidden "$hidden" \ + # Rolling (-l) listings are included. Resend duration as an integer (whole seconds) so auto-renew stays on. + # A float duration returns 400. Send duration OR end_date, never both. + # hidden_listing must be explicit. vol_size 0 avoids creating a volume offer. + body=$(echo "$machine" | jq -c --argjson hidden "$hidden" --arg vol "$VOL_SIZE" \ '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim, hidden_listing: $hidden} - + (if .duration == null then {end_date} else {duration: (.duration | floor)} end)') + + (if .duration == null then {end_date} else {duration: (.duration | floor)} end) + + (if $vol == "" then {} else {vol_size: ($vol|tonumber)} end)') if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi @@ -478,7 +488,7 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' + -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` Replace `CURRENT_END_DATE_UNIX` and `CURRENT_MIN_CHUNK` with the current values from `show machines`, as numbers with no quotes. A later `end_date` extends live SLA contracts. Omitting `min_chunk` resets it to 1. @@ -519,10 +529,11 @@ Replace `CURRENT_END_DATE_UNIX` and `CURRENT_MIN_CHUNK` with the current values ``` - `extended` — integer count of rental contracts extended (read from `results[0]`, not the top level) -- `new_contracts` / `upd_contracts` — arrays of listing contract IDs, not a signal that locked SLA terms on an active rental changed +- `new_contracts` — IDs of offers (asks) created by this call +- `upd_contracts` — IDs of active rental contracts whose end date this call extended. The count matches `extended`. -SLA field updates apply to the **offer** and to **new** rentals only. Existing rental contracts keep their locked reliability target and SLA fee until they end. `upd_contracts` and `new_contracts` describe listing maintenance, not changes to an active renter's locked SLA terms. +A non-empty `upd_contracts` means this request extended live rentals. Each contract keeps its locked reliability target and SLA fee, but its end date — and your service-credit exposure — now runs later. SLA field updates still apply to the **offer** and to **new** rentals only. ## Economics walkthrough From 5cd4e8ccb7b621d4a974f2cb0eb741344fbd863e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:51:00 -0700 Subject: [PATCH 156/250] docs(sla): address doc-review consensus (cycle 103) Align earnings timing, rent error codes, and min_chunk reset rules with the API. Co-authored-by: Cursor --- api-reference/openapi.yaml | 61 ++++++++++--------- .../openapi/yaml/create_instance.yaml | 10 +-- api-reference/openapi/yaml/list_machine.yaml | 4 +- cli/reference/show-earnings.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 6 +- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 20 +++--- 7 files changed, 53 insertions(+), 52 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 6c064cd5..f810bd71 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1654,15 +1654,13 @@ paths: type: number format: float minimum: 0 + maximum: 1 exclusiveMaximum: true - description: "Client SLA coverage target (greater than 0 and less\ - \ than 1). When set on an SLA-enabled offer\n(`sla_r_claim > 0`),\ - \ locks SLA terms on the new contract. Omit or set to 0 for a\ - \ non-SLA rental.\nUse the same value you used in search when\ - \ comparing `dph_total`.\nCommon failures: `invalid_sla_params`\ - \ when the offer has no SLA, the target is above the host commitment,\ - \ the target is out of range, or the SLA fee would exceed 1\xD7\ - \ compute.\nSee [SLA Coverage](/guides/instances/choosing/sla-coverage).\n" + description: "0 or omitted means no SLA. A value in (0, 1) requests\ + \ an SLA at that reliability target.\nValues below 0 or at least\ + \ 1 return HTTP 400 `invalid_args`.\n`invalid_sla_params` covers\ + \ an offer with no SLA, a target above the host commitment, or\ + \ an SLA fee above 1\xD7 compute.\nSee [SLA Coverage](/guides/instances/choosing/sla-coverage).\n" runtype: type: string description: 'Launch mode for the instance. If omitted, defaults @@ -1807,13 +1805,13 @@ paths: description: ID of the newly created instance contract example: 1234568 '400': - description: "Bad Request. SLA failures use `invalid_sla_params` (no SLA\ - \ on the offer, target above the host commitment, target out of range,\ - \ or SLA fee above 1\xD7 compute). Also SSH key requirements. A missing\ - \ offer is HTTP 400 `invalid_args` with `no_such_ask` (`msg` contains\ - \ `error 404/3603`). A host account renting someone else's offer is also\ - \ HTTP 400 `invalid_args` (`msg` contains `error 403/3586`). The HTTP\ - \ status is 400 in both cases.\n" + description: "Bad Request. Out-of-range `target_reliability` (below 0 or\ + \ at least 1) is `invalid_args`. `invalid_sla_params` covers no SLA on\ + \ the offer, a target above the host commitment, or an SLA fee above 1\xD7\ + \ compute. Also SSH key requirements. A missing offer is HTTP 400 `invalid_args`\ + \ with `no_such_ask` (`msg` contains `error 404/3603`). A host account\ + \ renting someone else's offer is also HTTP 400 `invalid_args` (`msg`\ + \ contains `error 403/3586`). The HTTP status is 400 in both cases.\n" content: application/json: schema: @@ -4506,18 +4504,20 @@ paths: \ rent on the vast.ai platform.\nAllows setting offer pricing, rental types,\ \ end dates, discount rates, and SLA parameters.\nUnspecified fields generally\ \ keep their current values, except `price_disk` (defaults to 0.10), `duration`\ - \ (cleared if omitted), `hidden_listing` (defaults to false), and `min_chunk`\ - \ (defaults to 1). Omitting `vol_size` on a machine with no volume offer creates\ - \ one at half the free disk; send `0` to opt out. Send `price_disk`, `hidden_listing`,\ - \ and `min_chunk` on every update. Send either `duration` or `end_date`, never\ - \ both (400). Read the current offer with show machines before changing pricing.\n\ - \nSLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`)\ - \ are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`.\ - \ Host-sent `sla_r_target` / legacy `sla_reliability` are ignored \u2014 clients\ - \ choose a reliability target at search/rent time. The published CLI and SDK\ - \ do not yet expose SLA fields \u2014 use the host console (**Set Pricing\ - \ \u2192 SLA**) or REST/`curl` until CLI/SDK support ships.\n\nCLI Usage (non-SLA\ - \ fields): `vastai list machine [options]`" + \ (cleared if omitted), `hidden_listing` (defaults to false), `min_chunk`\ + \ defaults to 1 only when offers are created or re-created, not when an existing\ + \ listing is updated. Omitting `vol_size` on a machine with no volume offer\ + \ creates one at half the free disk; send `0` to opt out. Send `price_disk`,\ + \ `hidden_listing`, and `min_chunk` on every update. Send either `duration`\ + \ or `end_date`, never both (400). Read the current offer with show machines\ + \ before changing pricing.\n\nSLA request-body fields (`sla_r_claim`, `sla_sigma_x`,\ + \ optional `sla_max_beta`) are supported on this REST endpoint. SLA activates\ + \ when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability`\ + \ are ignored \u2014 clients choose a reliability target at search/rent time.\ + \ The published CLI and SDK do not yet expose SLA fields \u2014 use the host\ + \ console (**Set Pricing \u2192 SLA**) or REST/`curl` until CLI/SDK support\ + \ ships.\n\nCLI Usage (non-SLA fields): `vastai list machine \ + \ [options]`" security: - BearerAuth: [] requestBody: @@ -4555,9 +4555,10 @@ paths: min_chunk: type: integer description: Minimum number of GPUs that must be rented together. - Omitted values reset to 1, which can slice a machine that was - previously whole-GPU only. Send the current listed_min_gpu_count - on every update. + Defaults to 1 when offers are created or re-created (first publish, + or relist after unlist). Omitting it on an already-listed machine + does not change the current minimum. Send listed_min_gpu_count + so a later relist does not slice the machine. default: 1 end_date: type: number diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index c2daed69..68de8ccb 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -73,12 +73,12 @@ paths: type: number format: float minimum: 0 + maximum: 1 exclusiveMaximum: true description: | - Client SLA coverage target (greater than 0 and less than 1). When set on an SLA-enabled offer - (`sla_r_claim > 0`), locks SLA terms on the new contract. Omit or set to 0 for a non-SLA rental. - Use the same value you used in search when comparing `dph_total`. - Common failures: `invalid_sla_params` when the offer has no SLA, the target is above the host commitment, the target is out of range, or the SLA fee would exceed 1× compute. + 0 or omitted means no SLA. A value in (0, 1) requests an SLA at that reliability target. + Values below 0 or at least 1 return HTTP 400 `invalid_args`. + `invalid_sla_params` covers an offer with no SLA, a target above the host commitment, or an SLA fee above 1× compute. See [SLA Coverage](/guides/instances/choosing/sla-coverage). runtype: type: string @@ -199,7 +199,7 @@ paths: example: 1234568 '400': description: | - Bad Request. SLA failures use `invalid_sla_params` (no SLA on the offer, target above the host commitment, target out of range, or SLA fee above 1× compute). Also SSH key requirements. A missing offer is HTTP 400 `invalid_args` with `no_such_ask` (`msg` contains `error 404/3603`). A host account renting someone else's offer is also HTTP 400 `invalid_args` (`msg` contains `error 403/3586`). The HTTP status is 400 in both cases. + Bad Request. Out-of-range `target_reliability` (below 0 or at least 1) is `invalid_args`. `invalid_sla_params` covers no SLA on the offer, a target above the host commitment, or an SLA fee above 1× compute. Also SSH key requirements. A missing offer is HTTP 400 `invalid_args` with `no_such_ask` (`msg` contains `error 404/3603`). A host account renting someone else's offer is also HTTP 400 `invalid_args` (`msg` contains `error 403/3586`). The HTTP status is 400 in both cases. content: application/json: schema: diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 50247e16..3b5c423d 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -13,7 +13,7 @@ paths: description: | Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. - Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted), `hidden_listing` (defaults to false), and `min_chunk` (defaults to 1). Omitting `vol_size` on a machine with no volume offer creates one at half the free disk; send `0` to opt out. Send `price_disk`, `hidden_listing`, and `min_chunk` on every update. Send either `duration` or `end_date`, never both (400). Read the current offer with show machines before changing pricing. + Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted), `hidden_listing` (defaults to false), `min_chunk` defaults to 1 only when offers are created or re-created, not when an existing listing is updated. Omitting `vol_size` on a machine with no volume offer creates one at half the free disk; send `0` to opt out. Send `price_disk`, `hidden_listing`, and `min_chunk` on every update. Send either `duration` or `end_date`, never both (400). Read the current offer with show machines before changing pricing. SLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are ignored — clients choose a reliability target at search/rent time. The published CLI and SDK do not yet expose SLA fields — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. @@ -54,7 +54,7 @@ paths: description: Minimum bid price allowed min_chunk: type: integer - description: Minimum number of GPUs that must be rented together. Omitted values reset to 1, which can slice a machine that was previously whole-GPU only. Send the current listed_min_gpu_count on every update. + description: Minimum number of GPUs that must be rented together. Defaults to 1 when offers are created or re-created (first publish, or relist after unlist). Omitting it on an already-listed machine does not change the current minimum. Send listed_min_gpu_count so a later relist does not slice the machine. default: 1 end_date: type: number diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index f84a1b09..7610f5b1 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -6,7 +6,7 @@ sidebarTitle: "show earnings" Get machine earnings history reports. -Host settlement command. For SLA contracts, `sla_earn` is the escrow released to the host that day (net compute plus the SLA fee, minus service credits), not a credit balance and not renter credits. SLA-contract compute is omitted from `gpu_earn`. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [Where do I see historical SLA credits?](/guides/instances/choosing/sla-coverage#where-do-i-see-historical-sla-credits). +Host settlement command. For SLA contracts, `sla_earn` is the escrow released to the host that day, not a credit balance and not renter credits. Releases are spread over time, so one low day is not by itself a service credit. SLA-contract compute is omitted from `gpu_earn`. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [Where do I see historical SLA credits?](/guides/instances/choosing/sla-coverage#where-do-i-see-historical-sla-credits). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index ae423a07..25131fcf 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -282,18 +282,18 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta **Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. -**Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/` (`target_reliability`, `instance.slaPremiumPerHour`). +**Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour`. Show-instances uses OpenAPI threshold `1.0` (about one request per second). | Symptom | Typical response | What to do | | --- | --- | --- | -| Target out of range (below 0 or 1 or above) | HTTP 400 `invalid_args` ("target reliability must be greater than or equal to 0 and less than 1") | Send a plain number in `[0, 1)`. | +| Target outside `[0, 1)` (negative, or 1 or above) | HTTP 400 `invalid_args` ("target reliability must be greater than or equal to 0 and less than 1") | SLA requires `0 < target_reliability < 1`. Sending `0` or omitting the field rents **without** an SLA (HTTP 200, no error). | | Offer has no SLA, target is above the host commitment, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | | SLA not enabled for the account or region | HTTP 403 `sla_disabled` | Contact support | | Offer no longer exists | HTTP 400 `invalid_args` (`no_such_ask`; `msg` may contain `error 404/3603`) or HTTP 410 | Re-search and use a fresh offer ID. The HTTP status for a missing offer is 400, not 404. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | Before sending the same `PUT` again, check `GET /api/v1/instances/` for a new contract. There is no idempotency key, so a blind retry can create a second paid rental. | -| Too many requests | HTTP 429. Search is about 10 requests per minute. Rent uses `threshold` 4.5; the body is `{"detail": ...}`, not `{success, error, msg}`. | Back off, then confirm with `GET /api/v1/instances/` whether the contract already exists. If retry returns `invalid_price`, `no_such_ask`, 404, or 410, re-search and rent a fresh offer id. | +| Too many requests | HTTP 429. Search is about 10 requests per minute. Space rent calls about 5 seconds apart (OpenAPI `x-rate-limit` threshold 4.5, penalty 12). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then confirm with `GET /api/v1/instances/` whether the contract already exists before you retry. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index f71292db..56804b96 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -255,7 +255,7 @@ Use these paths in order: 1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. 2. **Planned downtime with active renters:** Schedule at least 24 hours ahead from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). -3. **Emergency or unplanned downtime:** Notify renters immediately with [`vastai schedule maint`](/host/cli/schedule-maint). +3. **Emergency or unplanned downtime:** Notify renters immediately, either from the console ([Set a maintenance window](/host/set-maintenance-window)) or with [`vastai schedule maint`](/host/cli/schedule-maint). Use one path per window. For SLA maintenance-forgiveness rules, notice windows, and confirmation steps, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Forgiveness is not guaranteed, and it is not a payment to the host. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 8f47d7b7..f31c0a8d 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -276,7 +276,7 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons **Not a first listing.** Use this SLA-only body when the machine already has base pricing. For a **first publish**, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include at least `min_chunk`, disk/bandwidth prices, and `end_date`) or **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). -Omitted fields reset. Read the warning under [Full listing update](#full-listing-update-existing-ask) before you copy a body. `"vol_size": 0` keeps a new volume offer from being created. It does not delete a volume offer you already have. +Some omitted fields reset to defaults (for example `price_disk`, `hidden_listing`, and `duration`). Read the warning under [Full listing update](#full-listing-update-existing-ask) before you copy a body. `"vol_size": 0` keeps a new volume offer from being created. It does not delete a volume offer you already have. ```bash # "vol_size": 0 keeps volume offers off. Remove it only if this machine should have a volume offer. @@ -286,7 +286,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_END_DATE_UNIX` with the machine's current `end_date` from `show machines`, as a number with no quotes. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (omitting `min_chunk` resets it to 1). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. +Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_END_DATE_UNIX` with the machine's current `end_date` from `show machines`, as a number with no quotes. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (it defaults to 1 only when offers are created or re-created). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. Send your **current** `end_date` unless you intend to extend. A later `end_date` at the same or lower price extends existing rental contracts, including their SLA terms and service-credit exposure. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). @@ -342,7 +342,7 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - `price_disk` resets to **$0.10/GB/month** if omitted or `null`. - `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing). - `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. -- `min_chunk` resets to **1** if omitted, which can make a whole-GPU listing sliceable. Send the current `listed_min_gpu_count`. +- `min_chunk` defaults to **1** when offers are created or re-created (first publish, or relisting after an unlist). On an already-listed machine, omitting it does not change the current minimum. Still send `listed_min_gpu_count` so a later relist does not slice the machine by accident. - `vol_size` omitted on a machine with no volume offer creates one sized at half the free disk. Send `"vol_size": 0` to keep that from happening. `0` does not delete a volume offer that already exists. - Send **either** `duration` (integer seconds; a float such as `2592000.0` returns 400 `Invalid duration`) **or** `end_date`, never both. Sending both returns `400` `Cannot set both duration and end_date`. @@ -482,7 +482,7 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid -**SLA-only update (existing ask only)** — send `machine`, the current `price_disk`, `hidden_listing`, and either `duration` (integer seconds) or `end_date`, plus the SLA fields. Omitted fields reset as described in the warning above. Do **not** use this body for a first listing. Replace the placeholders with values from `show machines`. +**SLA-only update (existing ask only)** — send `machine`, the current `price_disk`, `hidden_listing`, and either `duration` (integer seconds) or `end_date`, plus the SLA fields. Some omitted fields reset, as described in the warning above. Do **not** use this body for a first listing. Replace the placeholders with values from `show machines`. ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ @@ -491,7 +491,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` -Replace `CURRENT_END_DATE_UNIX` and `CURRENT_MIN_CHUNK` with the current values from `show machines`, as numbers with no quotes. A later `end_date` extends live SLA contracts. Omitting `min_chunk` resets it to 1. +Replace `CURRENT_END_DATE_UNIX` and `CURRENT_MIN_CHUNK` with the current values from `show machines`, as numbers with no quotes. A later `end_date` extends live SLA contracts. `min_chunk` defaults to 1 only when offers are created or re-created, not on an update of a live listing. **Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. @@ -688,17 +688,17 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — Review reliability; re-run the backtester over the affected dates and check `escrow_to_client_balance` and `reliability` on those days. - **Severe outage (active SLA contracts):** - 1. Notify renters now: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. - 2. Stop new SLA rentals. The fastest way is `vastai unlist machine MACHINE_ID`, which publishes nothing. Setting the reliability commitment to `0` (`sla_r_claim=0`) only works while the machine is online. If it is down, `create_asks` returns HTTP 402 and `vastai unlist machine` is the path that works. Only change the commitment on machines that are currently listed, because `create_asks` publishes a live listing. Include the current `price_disk` on that update. + 1. **Notify renters.** In the console: **Host → Machines → Settings → Machine Maintenances** (see [Set a maintenance window](/host/set-maintenance-window)). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. + 2. **Stop new rentals.** In the console, use **Unlist** on **Host → Machines**. To automate: `vastai unlist machine MACHINE_ID`, which publishes nothing. Setting the reliability commitment to `0` (`sla_r_claim=0`) only works while the machine is online. If it is down, `create_asks` returns HTTP 402. Only change the commitment on machines that are currently listed, because `create_asks` publishes a live listing. Include the current `price_disk` on that update. 3. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. - 4. After the next UTC midnight, check `sla_earn` for the affected day. + 4. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`, or re-run the backtester and read `days[].escrow_to_client_balance`. 5. Contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. ## Monitoring SLA after listing After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). -For SLA contracts, `sla_earn` is the escrow released to you that day: your net compute earnings plus the SLA fee, minus any service credits paid to the renter. It matches the backtester's `escrow_to_host_balance`. SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not treat a smaller `sla_earn` as a negative credit, and do not compare it to the backtester's largest single-day credit. +For SLA contracts, `sla_earn` is the escrow released to you that day. It matches the backtester's `escrow_to_host_balance`. Releases are spread over time rather than paid out the same day, so an early or low day can be timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. @@ -708,7 +708,7 @@ When you poll the API, use **`per_machine[].sla_earn`** for a single machine. ** 2. Set the date range to include the UTC day you want to review. 3. Filter by machine ID if available. 4. Look for the SLA settlement in the earnings breakdown. On an SLA rental, compute pay is released with the SLA fee (the same amount as `sla_earn` in the API), not as a separate GPU earnings line. -5. After downtime, a smaller release than a normal day can mean a service credit was paid. Do not look for a negative SLA line, and do not match that amount to the backtester's largest single-day credit. +5. After downtime, compare several days with a normal week. A single smaller release can be timing, because escrow is released over time, not proof of a credit by itself. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. **If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). From 684369083fd53cec1f2c05bfe2844222dba72f4e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 17:51:16 -0700 Subject: [PATCH 157/250] docs(sla): fix list-machine min_chunk sentence (cycle 103) Co-authored-by: Cursor --- api-reference/openapi.yaml | 2 +- api-reference/openapi/yaml/list_machine.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index f810bd71..e3f67e41 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4504,7 +4504,7 @@ paths: \ rent on the vast.ai platform.\nAllows setting offer pricing, rental types,\ \ end dates, discount rates, and SLA parameters.\nUnspecified fields generally\ \ keep their current values, except `price_disk` (defaults to 0.10), `duration`\ - \ (cleared if omitted), `hidden_listing` (defaults to false), `min_chunk`\ + \ (cleared if omitted), `hidden_listing` (defaults to false). `min_chunk`\ \ defaults to 1 only when offers are created or re-created, not when an existing\ \ listing is updated. Omitting `vol_size` on a machine with no volume offer\ \ creates one at half the free disk; send `0` to opt out. Send `price_disk`,\ diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 3b5c423d..dbba1c0a 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -13,7 +13,7 @@ paths: description: | Creates or updates ask contracts for a machine to list it for rent on the vast.ai platform. Allows setting offer pricing, rental types, end dates, discount rates, and SLA parameters. - Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted), `hidden_listing` (defaults to false), `min_chunk` defaults to 1 only when offers are created or re-created, not when an existing listing is updated. Omitting `vol_size` on a machine with no volume offer creates one at half the free disk; send `0` to opt out. Send `price_disk`, `hidden_listing`, and `min_chunk` on every update. Send either `duration` or `end_date`, never both (400). Read the current offer with show machines before changing pricing. + Unspecified fields generally keep their current values, except `price_disk` (defaults to 0.10), `duration` (cleared if omitted), `hidden_listing` (defaults to false). `min_chunk` defaults to 1 only when offers are created or re-created, not when an existing listing is updated. Omitting `vol_size` on a machine with no volume offer creates one at half the free disk; send `0` to opt out. Send `price_disk`, `hidden_listing`, and `min_chunk` on every update. Send either `duration` or `end_date`, never both (400). Read the current offer with show machines before changing pricing. SLA request-body fields (`sla_r_claim`, `sla_sigma_x`, optional `sla_max_beta`) are supported on this REST endpoint. SLA activates when `sla_r_claim > 0`. Host-sent `sla_r_target` / legacy `sla_reliability` are ignored — clients choose a reliability target at search/rent time. The published CLI and SDK do not yet expose SLA fields — use the host console (**Set Pricing → SLA**) or REST/`curl` until CLI/SDK support ships. From ba4ea4d99fac4a2ff771766b43b3063f32455b49 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 18:04:09 -0700 Subject: [PATCH 158/250] docs(sla): address doc-review consensus (cycle 104) Document the listing rate limit, charge type sla, and which rentals an end date extends. Co-authored-by: Cursor --- api-reference/openapi.yaml | 13 +++++++++---- api-reference/openapi/yaml/create_instance.yaml | 2 +- api-reference/openapi/yaml/list_machine.yaml | 7 +++++++ api-reference/openapi/yaml/show_charges.yaml | 4 ++-- api-reference/permissions.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 8 +++----- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 14 +++++++------- 8 files changed, 32 insertions(+), 22 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index e3f67e41..5598f240 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1646,8 +1646,8 @@ paths: type: number format: float minimum: 8 - description: 'Size of local disk partition (in GB). Minimum 8 when - specified. + description: 'Size of local disk partition (in GB). Values below + 8 are raised to 8 with no error. ' target_reliability: @@ -4723,6 +4723,10 @@ paths: msg: type: string example: Machine is decommissioned or migration-locked + '402': + description: Machine daemon has not checked in recently. Message is in `results[0].msg`. + '429': + description: Too many requests. Space calls at least 5 seconds apart. tags: - Machines operationId: listMachine @@ -7461,8 +7465,8 @@ paths: items: type: array description: Per-charge-type breakdown (`gpu`, `disk`, `bwd`, - `bwu`). Empty for tree-format wrappers above the contract - level. + `bwu`, and `sla` on SLA rentals). Empty for tree-format + wrappers above the contract level. items: type: object properties: @@ -7479,6 +7483,7 @@ paths: - disk - bwd - bwu + - sla example: gpu source: type: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 68de8ccb..ba158d24 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -68,7 +68,7 @@ paths: format: float minimum: 8 description: | - Size of local disk partition (in GB). Minimum 8 when specified. + Size of local disk partition (in GB). Values below 8 are raised to 8 with no error. target_reliability: type: number format: float diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index dbba1c0a..f88e6499 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -201,8 +201,15 @@ paths: msg: type: string example: Machine is decommissioned or migration-locked + '402': + description: Machine daemon has not checked in recently. Message is in `results[0].msg`. + '429': + description: Too many requests. Space calls at least 5 seconds apart. tags: - Machines +x-rate-limit: + threshold: 5.0 + description: Maximum request frequency for PUT /api/v0/machines/create_asks/. Space calls at least 5 seconds apart. components: securitySchemes: BearerAuth: diff --git a/api-reference/openapi/yaml/show_charges.yaml b/api-reference/openapi/yaml/show_charges.yaml index e3721c19..2ed1e471 100644 --- a/api-reference/openapi/yaml/show_charges.yaml +++ b/api-reference/openapi/yaml/show_charges.yaml @@ -147,7 +147,7 @@ paths: example: 25355 items: type: array - description: Per-charge-type breakdown (`gpu`, `disk`, `bwd`, `bwu`). Empty for tree-format wrappers above the contract level. + description: Per-charge-type breakdown (`gpu`, `disk`, `bwd`, `bwu`, and `sla` on SLA rentals). Empty for tree-format wrappers above the contract level. items: type: object properties: @@ -159,7 +159,7 @@ paths: example: 1730678400 type: type: string - enum: [gpu, disk, bwd, bwu] + enum: [gpu, disk, bwd, bwu, sla] example: gpu source: type: string diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 51a13f1a..99cbf70e 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -120,10 +120,10 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if | Rent with an SLA | `instance_write` | Console **RENT** | | Verify `target_reliability` | `instance_read` | **Instances** | -**Service credits:** Use the web console (**Account → Billing**) to view SLA credits. The Charges API (`GET /api/v0/charges/`) and Invoices API (`GET /api/v1/invoices/`) do not include SLA settlement line items; charge `items[].type` is limited to `gpu`, `disk`, `bwd`, and `bwu`. +**Service credits:** Use the web console (**Account → Billing**) to view SLA credits. `GET /api/v0/charges/` can include `items[].type` `sla` (description **SLA Fee**) on SLA rentals, in addition to `gpu`, `disk`, `bwd`, and `bwu`. That row is the SLA fee for the period, not an itemized service credit. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. -OpenAPI lists charge `type` values only (`gpu`, `disk`, `bwd`, `bwu`). Do not use that endpoint alone to reconcile SLA credits. +Do not use the Charges API alone to reconcile service credits. The `sla` row is the fee, not the credit. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 25131fcf..6a24fac5 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -262,7 +262,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ }' ``` -`template_hash_id` is the content hash of a saved template. Include `template_hash_id` to rent from the template. Add `image` only when you want to override the template image. A request needs at least one of those fields. A template rent can send `template_hash_id` alone. Request fields override template defaults. `target_reliability` must match the value you searched with, and `disk` must meet the offer minimum, or rent can fail with `invalid_price`. See [Create Instance](/api-reference/instances/create-instance). +`template_hash_id` is the content hash of a saved template. Include `template_hash_id` to rent from the template. Add `image` only when you want to override the template image. A request needs at least one of those fields. A template rent can send `template_hash_id` alone. Request fields override template defaults. `disk` below 8 GB is raised to 8 GB with no error, so a CLI quote at the 5 GiB default will not match the billed storage. Rent returns `invalid_price` when the offer's GPU price exceeds the platform maximum, not because `target_reliability` changed. Re-search and use a fresh offer ID. See [Create Instance](/api-reference/instances/create-instance). **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Renter SLA scoped-key recipe](/api-reference/permissions#renter-sla-scoped-key-recipe). @@ -305,9 +305,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** before REST rent, or match the **same integer** on the console disk slider and REST `"disk"`. Example: `vastai search offers --storage 50` → console slider **50** → `"disk": 50` on `PUT /api/v0/asks/{id}/`. -**Match disk size when comparing prices.** Defaults differ by channel. When you rent with REST after a CLI search, pass the same number you searched with (for example `--storage 50` then `"disk": 50`). REST create-instance `disk` must be ≥ **8** when you pass it. The CLI search default of 5 is below that REST minimum. CLI help labels `--storage` as GiB and REST labels `disk` as GB. - -**Quoting rule:** Use the same disk number end-to-end for the channel you rent through (console slider, REST `disk` / `allocated_storage`, or CLI `--storage`). If you mix channels, set disk explicitly on every search and rent step. Treat the same integer as one quote across CLI GiB and REST GB labels unless the API returns a mismatch error (`invalid_price`). +**Match disk size when comparing prices.** REST create-instance raises `disk` values below 8 GB to 8 GB without an error. Search and rent with the same number, 8 or more, so the quote matches the bill. CLI help labels `--storage` as GiB and REST labels `disk` as GB. Vast treats the same integer as the same quote. ## What happens after you rent @@ -436,7 +434,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta **Console:** After UTC settlement, open **Account → Billing** and look for **service credit** or SLA credit line items (wording can vary)—not in the instance price panel. Credits are not available via the Charges API, invoices, or billing exports today. -**API integrators:** Prefer **Account → Billing** for service credit reconciliation. There is no renter API for SLA credits. Published OpenAPI for `GET /api/v0/charges/` documents charge `type` values `gpu`, `disk`, `bwd`, and `bwu` — not a dedicated SLA settlement type. `GET /api/v1/invoices/` covers payment transactions (top-ups, transfers, payouts), not SLA service-credit line items. Client webhooks for SLA credits are not available. Host-side settlement visibility uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`) — that path is for hosts, not renters. +**API integrators:** Prefer **Account → Billing** for service credit reconciliation. `GET /api/v0/charges/` can return `type: "sla"` with description **SLA Fee**. That amount is the SLA fee for the period, not an itemized service credit. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). ## Related documentation diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index a450c5e1..d4c3deb2 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -292,7 +292,7 @@ Optional, for API automation only. To check one machine, use the single-machine # Optional fallbacks for machines without SLA yet (machines with SLA keep their own terms): R=0.99 P=0.6667 BT_DIR=$(mktemp -d) trap 'rm -rf "$BT_DIR"' EXIT -machines=$(vastai show machines --raw) +machines=$(vastai show machines --raw --api-key "$VAST_API_KEY") for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f31c0a8d..dd581bb4 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -148,7 +148,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | | Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.99999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | -| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA fees for clients at a given target). Defaults to `0.5` when SLA is first enabled on an ask. On an existing SLA ask, omitting `sla_sigma_x` keeps the current value. | +| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA fees for clients at a given target). Defaults to `0.5` only on a **new** ask. When you first enable SLA on an existing listing, send `sla_sigma_x` yourself. Omitting it leaves the stored value empty, so `show machines` reports no confidence. On an ask that already has a stored value, omitting `sla_sigma_x` keeps that value. | ### Advanced: `sla_max_beta` (optional) @@ -200,7 +200,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.99999**. Exactly `1.0` is rejected. -- When the reliability commitment is positive, `sla_sigma_x` must be positive and at most `3.0`. It defaults to `0.5` when SLA is first enabled. On an existing SLA ask, omitting it keeps the current value. +- When the reliability commitment is positive, `sla_sigma_x` must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. On an existing listing, send it explicitly the first time you enable SLA. If a value is already stored, omitting it keeps that value. - Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. @@ -289,7 +289,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_END_DATE_UNIX` with the machine's current `end_date` from `show machines`, as a number with no quotes. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (it defaults to 1 only when offers are created or re-created). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. -Send your **current** `end_date` unless you intend to extend. A later `end_date` at the same or lower price extends existing rental contracts, including their SLA terms and service-credit exposure. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). +Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request would raise its price or SLA fee. Resending the offer's current `end_date` is not a no-op when some rentals end sooner. Check `results[0].upd_contracts` to see which contracts were extended. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). #### Full listing update (existing ask) @@ -357,7 +357,7 @@ vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12 REST equivalent: `GET /api/v0/machines/` (the CLI sends `?owner=me`). The account is the API key owner; a `?user_id=` query is ignored. -Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence` (`high` = Tight, `medium` = Normal, `low` = Wide), not as `sla_sigma_x`. `sla_reliability_claim` and `sla_confidence` are `null` unless **all** of these are true: SLA is enabled on the platform, the machine is listed, your account is SLA-approved, and the machine's daemon meets the SLA minimum version. A machine with saved SLA terms can still return `null` if it is unlisted, its daemon is outdated, or approval was revoked. A listed machine with SLA turned off returns `0`. Pricing fields and `end_date` are `null` when the machine is not listed. +Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence` (`high` = Tight, `medium` = Normal, `low` = Wide), not as `sla_sigma_x`. `null` means SLA was never stored on this ask, or the terms are hidden (unlisted machine, outdated daemon, or account not approved for SLA). `0` appears only when SLA was explicitly turned off and the terms are visible. Pricing fields and `end_date` are `null` when the machine is not listed. Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge → PUT). `vastai list machine` and the Python SDK listing helpers cannot set SLA fields; start from this REST pattern (or the console) when you move an existing CLI listing to SLA. @@ -416,7 +416,7 @@ DRY_RUN="${DRY_RUN:-1}" if [ "$DRY_RUN" = "0" ] && [ -z "$ALLOWLIST" ]; then echo "abort: set ALLOWLIST to Listed machine IDs before DRY_RUN=0" >&2; exit 1 fi -machines=$(vastai show machines --raw) +machines=$(vastai show machines --raw --api-key "$VAST_API_KEY") for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then echo "skip $id: not in ALLOWLIST"; continue @@ -469,7 +469,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do -d "$body") ok=$(echo "$resp" | jq -r '.success // empty') if [ "$ok" = "true" ]; then - echo "machine_id=$id ok" + echo "machine_id=$id ok extended=$(echo "$resp" | jq -c '.results[0].upd_contracts // []')" else echo "machine_id=$id error: $(echo "$resp" | jq -c '{success,error,msg}' 2>/dev/null || echo "$resp")" fi @@ -667,7 +667,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ `sdate` is Unix epoch seconds (UTC), at least 24 hours ahead for planned notice. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Cancel or reschedule:** To cancel a window, use [`vastai cancel maint`](/host/cli/cancel-maint) (requires `machine_write`) or the [REST cancel-maintenance API](/api-reference/machines/cancel-maint). To reschedule, cancel the existing window, then run `schedule maint` with a new `--sdate` (still ≥24 hours ahead for planned SLA maintenance). +**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. Windows Vast scheduled stay in place and are listed as `admin_locked`. To change one window, cancel, then create again every window you still want, at least 24 hours ahead, and confirm under **Settings → Machine Maintenances**. **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. From 294418898e0841dbd9dc9eb0b23ec1839cda5606 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 18:11:16 -0700 Subject: [PATCH 159/250] docs(sla): address doc-review consensus (cycle 105) Warn that fleet re-lists extend rentals, and match beta and CLI examples to the API. Co-authored-by: Cursor --- api-reference/openapi.yaml | 21 +++++++++++++++---- .../openapi/yaml/create_instance.yaml | 4 ++-- api-reference/openapi/yaml/list_machine.yaml | 2 +- api-reference/openapi/yaml/sla_backtest.yaml | 11 +++++++++- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 10 +++++++-- 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 5598f240..4c137fd1 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4601,9 +4601,11 @@ paths: type: number format: float description: "Host confidence spread \u2014 how wide your belief\ - \ is around the claim.\nMust be greater than 0 and at most 3.0.\ - \ Defaults to 0.5 when SLA is first enabled on an ask. Omitting\ - \ it on an existing SLA ask keeps the current value.\n" + \ is around the claim.\nSLA confidence spread. Defaults to 0.5\ + \ when an ask is created with SLA. When enabling SLA on an existing\ + \ ask, send it explicitly; omitting it keeps the stored value,\ + \ which may be empty. In that case show machines returns sla_confidence\ + \ null.\n" sla_max_beta: type: number format: float @@ -9349,7 +9351,8 @@ paths: (inclusive); the default lookback is 90 days when custom dates are omitted. Unknown query - parameters are rejected with `400 bad_request`. + parameters are rejected with `400 bad_request`. Optional `beta` is accepted + and ignored for hosts. Requires `machine_read` permission and ownership of the machine. See @@ -9413,6 +9416,16 @@ paths: schema: type: number description: Range end as Unix epoch seconds. Default is now. + - name: beta + in: query + required: false + deprecated: true + schema: + type: number + minimum: 0 + maximum: 1 + description: Not a host setting. Accepted for compatibility and ignored. The + value used is echoed in params.beta. responses: '200': description: Successful response diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index ba158d24..af78ce2e 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -327,5 +327,5 @@ x-cli-commands: method: PUT examples: - vastai create instance 1234567 --image tensorflow/tensorflow:latest-gpu --disk 32 - - vastai create instance 1234567 --template abc123def456 - - vastai create instance 1234567 --price 0.4 --disk 100 --env JUPYTER_TOKEN=abc123 \ No newline at end of file + - vastai create instance 1234567 --template_hash abc123def456 + - vastai create instance 1234567 --bid_price 0.4 --disk 100 --env JUPYTER_TOKEN=abc123 \ No newline at end of file diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index f88e6499..d6f9008f 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -87,7 +87,7 @@ paths: format: float description: | Host confidence spread — how wide your belief is around the claim. - Must be greater than 0 and at most 3.0. Defaults to 0.5 when SLA is first enabled on an ask. Omitting it on an existing SLA ask keeps the current value. + SLA confidence spread. Defaults to 0.5 when an ask is created with SLA. When enabling SLA on an existing ask, send it explicitly; omitting it keeps the stored value, which may be empty. In that case show machines returns sla_confidence null. sla_max_beta: type: number format: float diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index d814f19d..98d69576 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -16,7 +16,7 @@ paths: SLA settlement under what-if SLA terms, and returns a per-day ledger of the money that moved between the renter, the SLA escrow, and the host. The maximum date range is 366 days (inclusive); the default lookback is 90 days when custom dates are omitted. Unknown query - parameters are rejected with `400 bad_request`. + parameters are rejected with `400 bad_request`. Optional `beta` is accepted and ignored for hosts. Requires `machine_read` permission and ownership of the machine. See [SLA Earnings Backtester](/host/sla-backtester) for the usage guide. @@ -72,6 +72,15 @@ paths: schema: type: number description: Range end as Unix epoch seconds. Default is now. + - name: beta + in: query + required: false + deprecated: true + schema: + type: number + minimum: 0 + maximum: 1 + description: Not a host setting. Accepted for compatibility and ignored. The value used is echoed in params.beta. responses: '200': description: Successful response diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 6a24fac5..f3120301 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -338,7 +338,7 @@ When a host schedules maintenance in advance, part of that downtime is counted a ### Credit scenarios (simplified) -Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host reliability commitment 99%): +Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host reliability commitment 99%). A day's service credit is capped relative to that UTC day's covered compute (GPU, storage, and bandwidth combined). The dollar figures below use GPU cost only. | Scenario | Approx. SLA fee | Approx. service credit | Net vs no SLA (approx.) | | --- | --- | --- | --- | diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index d4c3deb2..59e324be 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -88,7 +88,7 @@ Requires Bearer authentication. Rate-limited to about one request every two seco | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | -`beta` is not a host setting. If sent, it must be between 0 and 1 and is otherwise ignored; the value actually used is echoed in `params.beta`. Any other unknown query parameter is rejected with `400 bad_request`. The older `r` and `reliability` parameters are no longer accepted; use `r_claim` (and `r_target`). +`beta` is not a host setting. If you send it, it must be between 0 and 1. Any valid value is ignored, and the value actually used is echoed in `params.beta`. Any other unknown query parameter is rejected with `400 bad_request`. The older `r` and `reliability` parameters are no longer accepted; use `r_claim` (and `r_target`). ### Limits diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index dd581bb4..03c7ca09 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -141,6 +141,8 @@ On sliced machines, SLA settles **per rental contract**. If one GPU slice fails For SLA-covered on-demand contracts, compute billing uses the **intended daily compute** for the rental. Offline time is tracked as an outage in reliability observations. Client compensation for poor reliability flows through **service credits**, not by silently zeroing the day's compute bill. +**Where SLA money goes.** On an SLA rental, the renter's compute payment and SLA fee are held by Vast (escrow) instead of being paid to you right away. Service credits are paid from that held money, and the rest is released to you over the following days. Those earnings show up as **SLA** earnings (`sla_earn`), not GPU earnings. See [How SLA money moves](/host/sla-backtester#how-sla-money-moves). + ## SLA parameters When you list or update a machine, set SLA fields via the host console or `PUT /api/v0/machines/create_asks/` (see [Listing an SLA offer](#listing-an-sla-offer) below). @@ -367,6 +369,10 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge **Console hosts:** skip this section. Enable an SLA with [Web console](#web-console) and check settlement in [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). + +Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. Re-list only machines whose rentals already end on or after the offer end date, or accept the extension. After a live run, read `upd_contracts` in the output. + + Use this loop to republish SLA terms across a fleet, for example after a daemon update. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. `show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. @@ -471,7 +477,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ "$ok" = "true" ]; then echo "machine_id=$id ok extended=$(echo "$resp" | jq -c '.results[0].upd_contracts // []')" else - echo "machine_id=$id error: $(echo "$resp" | jq -c '{success,error,msg}' 2>/dev/null || echo "$resp")" + echo "machine_id=$id error: $(echo "$resp" | jq -c '{success, error: (.error // .results[0].error), msg: (.msg // .results[0].msg)}' 2>/dev/null || echo "$resp")" fi sleep 5 done @@ -506,7 +512,7 @@ Replace `CURRENT_END_DATE_UNIX` and `CURRENT_MIN_CHUNK` with the current values | 400 | `invalid_args` | Machine ID not found for your account, or malformed / incompatible request body | | 400 | `invalid_sla_params` | SLA parameters failed validation | | 429 | *(rate limited)* | Too many requests. Space fleet calls at least 5 seconds apart, then retry the machines that failed | -| 402 | `msg`: `can only create asks for an online machine` | The daemon has not checked in for more than 60 seconds. Wait until **Host → Machines** shows the machine online, then retry. If the machine is down, use `vastai unlist machine MACHINE_ID` instead. | +| 402 | `results[0].msg`: `error: can only create asks for an online machine.` | The daemon has not checked in for more than 60 seconds. Bring the machine online, then retry. If the machine is down, use `vastai unlist machine MACHINE_ID` instead. | **`machine_locked`:** Returned when a machine is decommissioned or migration-locked. If you are migrating hardware, finish or cancel active rentals first, remove or update the listing as needed, and contact support if the machine remains locked. Existing SLA terms on active contracts remain in force until those contracts end. From 7b004e12ceca05f2dc36a70f267743525e511af1 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 18:23:28 -0700 Subject: [PATCH 160/250] docs(sla): address doc-review consensus (cycle 106) Fix broken backtester links, and stop hidden listings and outage updates from changing live rentals. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-backtester.mdx | 2 ++ host/sla-offers.mdx | 2 +- sdk/python/reference/create-instance.mdx | 5 +++-- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index f3120301..161db884 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -292,8 +292,8 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Offer no longer exists | HTTP 400 `invalid_args` (`no_such_ask`; `msg` may contain `error 404/3603`) or HTTP 410 | Re-search and use a fresh offer ID. The HTTP status for a missing offer is 400, not 404. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | -| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | Before sending the same `PUT` again, check `GET /api/v1/instances/` for a new contract. There is no idempotency key, so a blind retry can create a second paid rental. | -| Too many requests | HTTP 429. Search is about 10 requests per minute. Space rent calls about 5 seconds apart (OpenAPI `x-rate-limit` threshold 4.5, penalty 12). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then confirm with `GET /api/v1/instances/` whether the contract already exists before you retry. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Before resending, `GET /api/v1/instances/?select_filters={"label":{"eq":"YOUR_LABEL"}}`. If a row exists, do not PUT again. | +| Too many requests | HTTP 429. Search is about 10 requests per minute. Space rent calls about 5 seconds apart (OpenAPI `x-rate-limit` threshold 4.5, penalty 12). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 59e324be..893480d9 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -43,12 +43,14 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 3. It replays those days as **one simulated SLA contract** through production SLA settlement. 4. It returns one row per UTC day showing the money that moved that day, plus two summary reliabilities (`r_eff`, `r_be`). + **How SLA money moves.** On an SLA contract, the renter's daily compute payment and SLA fee go into an SLA escrow for that contract. Escrow pays service credits to the renter and releases the rest to you. Each row in `days` shows those four flows for one day. Over the full window, what went in equals what came out, so your **net SLA result** is the SLA fees paid in minus the service credits paid out. **Simulated vs live renters.** If you omit `r_target`, the simulation assumes the renter targeted your full reliability commitment (`r_target = r_claim`). That is a conservative what-if: it produces the highest SLA fees and the most credit exposure. Live renters choose their own targets, often below your commitment. Pass `r_target` (for example `0.95` with `r_claim=0.99`) to model those renters. **Active vs idle days.** Days with no rental earnings appear as rows with all flows `0` and `reliability: null`. They are not outages: the simulated contract simply pauses. + **Simulation limits** - The whole machine is replayed as one contract. Live settlement runs per rental contract, so several concurrent SLA renters on a sliced machine can produce more credits on one day than the simulation shows. Pair this output with [SLA and GPU slicing](/host/sla-offers#sla-and-gpu-slicing). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 03c7ca09..257de7dc 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -695,7 +695,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **Unexpected credit** — Review reliability; re-run the backtester over the affected dates and check `escrow_to_client_balance` and `reliability` on those days. - **Severe outage (active SLA contracts):** 1. **Notify renters.** In the console: **Host → Machines → Settings → Machine Maintenances** (see [Set a maintenance window](/host/set-maintenance-window)). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. - 2. **Stop new rentals.** In the console, use **Unlist** on **Host → Machines**. To automate: `vastai unlist machine MACHINE_ID`, which publishes nothing. Setting the reliability commitment to `0` (`sla_r_claim=0`) only works while the machine is online. If it is down, `create_asks` returns HTTP 402. Only change the commitment on machines that are currently listed, because `create_asks` publishes a live listing. Include the current `price_disk` on that update. + 2. **Unlist the machine** in the console (**Host → Machines**), or run `vastai unlist machine MACHINE_ID`. This removes the listing and does not republish it. Do not send a `create_asks` update (for example `sla_r_claim=0`) during an outage: it fails with HTTP 402 while the machine is offline, and when it succeeds it resends `end_date`, which can extend active non-SLA rentals. 3. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 4. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`, or re-run the backtester and read `days[].escrow_to_client_balance`. 5. Contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 34ccae4f..b291aac1 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -194,6 +194,7 @@ response = requests.put( "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", "disk": 50, "target_reliability": 0.95, + "label": "rent-YOUR-UUID", }, timeout=60, ) @@ -201,8 +202,8 @@ if not response.ok: print(response.status_code, response.text) # body contains error / msg response.raise_for_status() print(response.json()) # new_contract is the rental instance ID -# On a timeout, dropped connection, 429, or 5xx the rental may already exist: -# check GET /api/v1/instances/ before sending the same PUT again. +# On a timeout, dropped connection, 429, or 5xx the rental may already exist. +# Look up label=rent-YOUR-UUID on GET /api/v1/instances/ before sending the same PUT again. ``` The same call with curl: diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 489e463a..56e6c748 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. Update hidden SLA listings through REST. ## Usage diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 05bc031b..f4629405 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `end_date` is on this method and on that REST call. `duration`, `vol_size`, and `vol_price` are REST body fields; the CLI flags `-l`, `-v`, and `-z` send them. If you previously opted out of volume offers, send `"vol_size": 0` on every update, or a volume offer is created when none exists. Follow the read → merge → PUT rule in [Offering SLA](/host/sla-offers): send back `price_disk`, `hidden_listing` when the listing is hidden, and either `duration` (auto-renew) or `end_date`. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `list_machine()` cannot send `hidden_listing`. A later reprice through the SDK or CLI makes a hidden listing public and can reset storage price and auto-renew. Update hidden SLA listings with REST and send `hidden_listing` explicitly. ## Signature From 4511e48fdcb574f4df0efc0d6614b8dde32d38ce Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 18:29:25 -0700 Subject: [PATCH 161/250] docs(sla): address doc-review consensus (cycle 107) Put a rent label on the copy-paste examples, and document backtester auth_error statuses. Co-authored-by: Cursor --- api-reference/openapi.yaml | 16 +++++++++++----- api-reference/openapi/yaml/sla_backtest.yaml | 10 +++++++--- guides/instances/choosing/sla-coverage.mdx | 10 ++++++---- sdk/python/reference/create-instance.mdx | 4 +++- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 4c137fd1..a0bf1b10 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9570,11 +9570,12 @@ paths: msg: type: string '401': - description: "Unauthorized \u2014 missing or invalid API key, or missing\ - \ machine_read permission" + description: Unauthorized. `error` is `auth_error` for an unknown or invalid + API key, or a key that lacks `machine_read`. '403': - description: "Forbidden \u2014 not the machine owner, or SLA is not currently\ - \ enabled on the platform" + description: Forbidden. `error` is `auth_error` when the Authorization header + is missing ("This action requires login."), `not_owner` when the machine + belongs to someone else, or `sla_disabled` when SLA is off for the platform. content: application/json: schema: @@ -9586,12 +9587,14 @@ paths: error: type: string enum: + - auth_error - not_owner - sla_disabled msg: type: string '404': - description: Machine not found + description: Machine not found (`machine_not_found`), or a malformed API + key (`auth_error`, "Invalid user key"). content: application/json: schema: @@ -9602,6 +9605,9 @@ paths: example: false error: type: string + enum: + - machine_not_found + - auth_error example: machine_not_found '429': description: "Too Many Requests \u2014 rate limit exceeded" diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index 98d69576..c657ecd1 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -205,9 +205,9 @@ paths: msg: type: string '401': - description: Unauthorized — missing or invalid API key, or missing machine_read permission + description: Unauthorized. `error` is `auth_error` for an unknown or invalid API key, or a key that lacks `machine_read`. '403': - description: Forbidden — not the machine owner, or SLA is not currently enabled on the platform + description: Forbidden. `error` is `auth_error` when the Authorization header is missing ("This action requires login."), `not_owner` when the machine belongs to someone else, or `sla_disabled` when SLA is off for the platform. content: application/json: schema: @@ -219,12 +219,13 @@ paths: error: type: string enum: + - auth_error - not_owner - sla_disabled msg: type: string '404': - description: Machine not found + description: Machine not found (`machine_not_found`), or a malformed API key (`auth_error`, "Invalid user key"). content: application/json: schema: @@ -235,6 +236,9 @@ paths: example: false error: type: string + enum: + - machine_not_found + - auth_error example: machine_not_found '429': description: Too Many Requests — rate limit exceeded diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 161db884..eb5ce695 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -241,11 +241,12 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ -d '{ "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", "disk": 50, - "target_reliability": 0.95 + "target_reliability": 0.95, + "label": "rent-YOUR-UUID" }' ``` -On-demand REST rent with default `cancel_unavail` may return **HTTP 410** if the offer cannot start immediately. Re-search and pick a new ask—do not backoff-retry the same id (see the error table below). +On-demand REST rent with default `cancel_unavail` may return **HTTP 410** if the offer cannot start immediately. Re-search and pick a new offer—do not backoff-retry the same id (see the error table below). Use a new `label` on each attempt. See [Create Instance](/api-reference/instances/create-instance) and [Search Offers](/api-reference/search/search-offers). @@ -258,7 +259,8 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ -d '{ "template_hash_id": "YOUR_TEMPLATE_HASH", "disk": 50, - "target_reliability": 0.95 + "target_reliability": 0.95, + "label": "rent-YOUR-UUID" }' ``` @@ -292,7 +294,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Offer no longer exists | HTTP 400 `invalid_args` (`no_such_ask`; `msg` may contain `error 404/3603`) or HTTP 410 | Re-search and use a fresh offer ID. The HTTP status for a missing offer is 400, not 404. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | -| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Before resending, `GET /api/v1/instances/?select_filters={"label":{"eq":"YOUR_LABEL"}}`. If a row exists, do not PUT again. | +| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Before resending, look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`). If a row exists, do not PUT again. | | Too many requests | HTTP 429. Search is about 10 requests per minute. Space rent calls about 5 seconds apart (OpenAPI `x-rate-limit` threshold 4.5, penalty 12). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index b291aac1..301b2088 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -204,6 +204,7 @@ if not response.ok: print(response.json()) # new_contract is the rental instance ID # On a timeout, dropped connection, 429, or 5xx the rental may already exist. # Look up label=rent-YOUR-UUID on GET /api/v1/instances/ before sending the same PUT again. +# URL-encode select_filters (curl -G --data-urlencode). ``` The same call with curl: @@ -215,7 +216,8 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ -d '{ "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", "disk": 50, - "target_reliability": 0.95 + "target_reliability": 0.95, + "label": "rent-YOUR-UUID" }' ``` From c425ab32691024640b104a35ee38ffc72bb4b9f9 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 18:37:38 -0700 Subject: [PATCH 162/250] docs(sla): address doc-review consensus (cycle 108) Save listing terms before an outage unlist, and correct CLI price-filter and earnings-window wording. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 ++ cli/reference/search-offers.mdx | 2 +- cli/reference/show-earnings.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 19 +++++++++++++------ 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 99cbf70e..e037cbf8 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -101,6 +101,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. - **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (v0 `show instances` omits SLA fields). On a running instance, the SLA fee is `instance.slaPremiumPerHour`; before running, use `search.slaPremiumPerHour`. +- **Charges:** add `billing_read` only if you read `sla` fee rows on `GET /api/v0/charges/`. The minimum key above cannot call Charges. ```json { @@ -297,6 +298,7 @@ SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for - [Search Invoices](/api-reference/billing/search-invoices) - [Show Invoices](/api-reference/billing/show-invoices) - [Show Earnings](/api-reference/billing/show-earnings) +- [Show Charges](/api-reference/billing/show-charges) (`GET /api/v0/charges/`) ### billing\_write diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 796f0084..12e14620 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -187,7 +187,7 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. **Response-only** SLA pricing fields in `--raw` output include `dph_total` (sort via `--order dph_total`) and `search.slaPremiumPerHour`; they are not CLI filter fields. Do **not** put `dph_total` in the query string. +**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. In `--raw` output, `dph_total` (also a sort field via `--order dph_total`) and `search.slaPremiumPerHour` are the SLA price fields. `dph_total` (alias `dph`) is also accepted as a CLI query filter, but the CLI cannot send `target_reliability`, so that filter compares the price **without** the SLA fee. To filter on the SLA-inclusive price, use the console or `POST /api/v0/bundles/` with `target_reliability`. | Field | Meaning | | --- | --- | diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index 7610f5b1..17314756 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -3,7 +3,7 @@ title: "vastai show earnings" sidebarTitle: "show earnings" --- -Get machine earnings history reports. +Get machine earnings history reports. With no dates, the server returns the previous UTC day. For a settlement check, pass explicit `T00:00:00Z` dates. Host settlement command. For SLA contracts, `sla_earn` is the escrow released to the host that day, not a credit balance and not renter credits. Releases are spread over time, so one low day is not by itself a service credit. SLA-contract compute is omitted from `gpu_earn`. Renters: [Account → Billing](https://cloud.vast.ai/billing/) — see [Where do I see historical SLA credits?](/guides/instances/choosing/sla-coverage#where-do-i-see-historical-sla-credits). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index eb5ce695..c5e6fa7f 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -348,7 +348,7 @@ Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host re | Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (net credit after SLA fee) | | Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | -**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without the SLA. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day that meets the target does not pay a credit. +**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without the SLA. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day where the **blended measure** meets your target does not pay a credit. Raw daily uptime can sit at or slightly above the target while the blended measure is still below it. Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 56804b96..d5ce2d52 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -193,7 +193,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. +To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. Moving the end date later extends every shorter active rental, including its SLA exposure, to the new date. If the same change would raise an existing contract's SLA fee, that contract is not extended. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). If you have raised the pricing, you cannot extend the current rental contracts. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 257de7dc..954e5617 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -694,14 +694,20 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — Review reliability; re-run the backtester over the affected dates and check `escrow_to_client_balance` and `reliability` on those days. - **Severe outage (active SLA contracts):** + 0. **Before you unlist, save your listing terms.** After unlist, `show machines` returns `null` for prices, `min_chunk`, `end_date`, and SLA terms. Confidence (`sla_sigma_x`) is never returned, so write down Tight, Normal, or Wide as well. + ```bash + vastai show machines --raw --api-key "$VAST_API_KEY" | jq '.machines[] | select(.id==MACHINE_ID)' > machine-MACHINE_ID-pre-outage.json + ``` 1. **Notify renters.** In the console: **Host → Machines → Settings → Machine Maintenances** (see [Set a maintenance window](/host/set-maintenance-window)). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. - 2. **Unlist the machine** in the console (**Host → Machines**), or run `vastai unlist machine MACHINE_ID`. This removes the listing and does not republish it. Do not send a `create_asks` update (for example `sla_r_claim=0`) during an outage: it fails with HTTP 402 while the machine is offline, and when it succeeds it resends `end_date`, which can extend active non-SLA rentals. + 2. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 3. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 4. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`, or re-run the backtester and read `days[].escrow_to_client_balance`. - 5. Contact [Discord](https://discord.gg/hSuEbSQ4X8) before relisting. + 5. When you relist, rebuild the listing from the snapshot (`price_disk`, `min_chunk`, `end_date` or `duration`, `hidden_listing`, `sla_r_claim`, `sla_sigma_x`). If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing +On SLA rentals, compute pay and the SLA fee are released together as SLA earnings over several days. A single smaller release can be timing. By itself it is not proof of a credit. + After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). For SLA contracts, `sla_earn` is the escrow released to you that day. It matches the backtester's `escrow_to_host_balance`. Releases are spread over time rather than paid out the same day, so an early or low day can be timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. @@ -710,9 +716,9 @@ When you poll the API, use **`per_machine[].sla_earn`** for a single machine. ** ### Console (recommended for day-to-day checks) -1. Go to **Host → Billing** (or **Earnings** / **Reports**). +1. Go to **Host → Billing**. 2. Set the date range to include the UTC day you want to review. -3. Filter by machine ID if available. +3. Machine filtering is not available in the console. For one machine, use `vastai show earnings --machine_id ID`. 4. Look for the SLA settlement in the earnings breakdown. On an SLA rental, compute pay is released with the SLA fee (the same amount as `sla_earn` in the API), not as a separate GPU earnings line. 5. After downtime, compare several days with a normal week. A single smaller release can be timing, because escrow is released over time, not proof of a credit by itself. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. @@ -766,14 +772,15 @@ Weekly aggregates are window totals, not daily series — use a one-day range ab This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, one pull with `last_days=1` after UTC rollover is usually enough. -**Automation pattern:** There is no host webhook for SLA settlement. Poll `machine-earnings` and read `per_machine[].sla_earn` (the escrow released that day, not a credit balance). Call machines sequentially with backoff on 429. Do not use `per_day[].sla_earn` for a single machine. +**Automation pattern:** There is no host webhook for SLA settlement. One fleet call with `sday` and `eday` set to the same day index returns that UTC day for every machine in `per_machine[]`. Use `machid` only for a spot check. Do not use `per_day[].sla_earn` for a single machine. `last_days=1` is coarse: it covers yesterday and the current UTC day so far, not one settled day. When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** - **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. To cross-check the backtester, compare `sla_earn` with that day's `escrow_to_host_balance`. Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. -- **Fleet snapshot (coarse / recent window only):** one request without `machid` returns all machines in `per_machine[]` for the window. +- **Fleet, exact UTC day (one call):** omit `machid` and set `sday` and `eday` to the same day index. Read `per_machine[].sla_earn`. +- **Recent window (`last_days`, coarse):** one request without `machid` returns all machines in `per_machine[]`. `last_days=1` spans yesterday and today-so-far. ```bash From 36b54771044938d3a40798a5470aa923f1ddb8b4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 18:44:25 -0700 Subject: [PATCH 163/250] docs(sla): address doc-review consensus (cycle 109) Stop the outage snapshot from writing an empty file, and give console hosts a Claim=0 path plus a consistent Service Credit label. Co-authored-by: Cursor --- api-reference/openapi.yaml | 4 +-- api-reference/openapi/yaml/sla_backtest.yaml | 4 +-- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 4 +-- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 4 +-- host/sla-offers.mdx | 34 +++++++++++++------- 7 files changed, 32 insertions(+), 22 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index a0bf1b10..c9cadf88 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9525,12 +9525,12 @@ paths: success: true machine_id: 12345 has_data: true - start_day: 20568 + start_day: 20567 end_day: 20657 r_eff: 0.9987 r_be: 0.9712 days: - - day: 20568 + - day: 20567 client_compute_to_escrow: 78.12 client_premium_to_escrow: 0.19 escrow_to_client_balance: 0.0 diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index c657ecd1..f4939dc7 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -165,12 +165,12 @@ paths: success: true machine_id: 12345 has_data: true - start_day: 20568 + start_day: 20567 end_day: 20657 r_eff: 0.9987 r_be: 0.9712 days: - - day: 20568 + - day: 20567 client_compute_to_escrow: 78.12 client_premium_to_escrow: 0.19 escrow_to_client_balance: 0.0 diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index d4907263..45114554 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -115,4 +115,4 @@ Startup time depends on the template and is usually under 5 minutes. If waiting - Note: You're not charged while instances are loading - With slow internet and large images, downloads can take an hour or more -If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy** to stop ongoing compute charges (stopping alone may not end all billing—see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage) when you used an SLA). Destroy permanently deletes the instance and its disk, so copy off anything you need first. +If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy**. Destroy ends the rental and permanently deletes the instance and its disk, so copy off anything you need first. If you rented with an SLA, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c5e6fa7f..72ed8f89 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -294,7 +294,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Offer no longer exists | HTTP 400 `invalid_args` (`no_such_ask`; `msg` may contain `error 404/3603`) or HTTP 410 | Re-search and use a fresh offer ID. The HTTP status for a missing offer is 400, not 404. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | -| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Before resending, look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`). If a row exists, do not PUT again. | +| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | | Too many requests | HTTP 429. Search is about 10 requests per minute. Space rent calls about 5 seconds apart (OpenAPI `x-rate-limit` threshold 4.5, penalty 12). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | @@ -434,7 +434,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing** and look for **service credit** or SLA credit line items (wording can vary)—not in the instance price panel. Credits are not available via the Charges API, invoices, or billing exports today. +**Console:** After UTC settlement, open **Account → Billing** and look for **Service Credit** — not in the instance price panel. Credits are not available via the Charges API, invoices, or billing exports today. **API integrators:** Prefer **Account → Billing** for service credit reconciliation. `GET /api/v0/charges/` can return `type: "sla"` with description **SLA Fee**. That amount is the SLA fee for the period, not an itemized service credit. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index d5ce2d52..73374d1a 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -193,7 +193,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. Moving the end date later extends every shorter active rental, including its SLA exposure, to the new date. If the same change would raise an existing contract's SLA fee, that contract is not extended. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. Moving the end date later extends every shorter active rental, including its SLA exposure, to the new date. If the request that moves the end date later also changes SLA terms in a way that would raise an existing contract's SLA fee (a lower commitment, wider confidence, or turning SLA off), that contract is not extended. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). If you have raised the pricing, you cannot extend the current rental contracts. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 893480d9..e3a6215e 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -150,13 +150,13 @@ A successful response looks like this (one `days` row shown; values are illustra "success": true, "machine_id": 12345, "has_data": true, - "start_day": 20568, + "start_day": 20567, "end_day": 20657, "r_eff": 0.9987, "r_be": 0.9712, "days": [ { - "day": 20568, + "day": 20567, "client_compute_to_escrow": 78.12, "client_premium_to_escrow": 0.19, "escrow_to_client_balance": 0.0, diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 954e5617..8747c39b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -221,7 +221,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. If the same request would raise the SLA fee on an existing SLA contract (lower commitment, wider confidence, or `sla_r_claim` set to `0`), that contract is not extended, and the response does not say so. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. If the request that moves `end_date` later also changes SLA terms in a way that would raise an existing contract's SLA fee (a lower commitment, wider confidence, or `sla_r_claim` set to `0`), that contract is not extended, and the response does not say so. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -244,7 +244,8 @@ If the machine is already **listed**: 1. Open **Host → Machines → Set Pricing → SLA**, set Claim and Confidence, then click **Save**. 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. -3. Verify after listing: +3. To stop offering SLA on **new** rentals, set **Claim** to `0` and **Save**. On an already-listed machine, **Save** updates the live offer; you do not need to click **LIST** again. Active contracts keep their SLA terms until they end. API users: send the full `create_asks` body with `"sla_r_claim": 0` (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). +4. Verify after listing: - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. - **Search:** `dph_total` includes the SLA fee at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). @@ -694,23 +695,32 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — Review reliability; re-run the backtester over the affected dates and check `escrow_to_client_balance` and `reliability` on those days. - **Severe outage (active SLA contracts):** - 0. **Before you unlist, save your listing terms.** After unlist, `show machines` returns `null` for prices, `min_chunk`, `end_date`, and SLA terms. Confidence (`sla_sigma_x`) is never returned, so write down Tight, Normal, or Wide as well. + 1. **Save your current terms before you unlist.** After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, and SLA terms. The snapshot does not include confidence (`sla_sigma_x`; only the `sla_confidence` label) or hidden status (`hidden_listing`). Write both down either way. + + **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, and Confidence (Tight, Normal, or Wide). + ```bash - vastai show machines --raw --api-key "$VAST_API_KEY" | jq '.machines[] | select(.id==MACHINE_ID)' > machine-MACHINE_ID-pre-outage.json + vastai show machines --raw --api-key "$VAST_API_KEY" \ + | jq -e '.machines[] | select((.id|tostring) == "MACHINE_ID")' \ + > machine-MACHINE_ID-pre-outage.json \ + && [ -s machine-MACHINE_ID-pre-outage.json ] \ + || echo "Snapshot is EMPTY: do not unlist yet" >&2 ``` - 1. **Notify renters.** In the console: **Host → Machines → Settings → Machine Maintenances** (see [Set a maintenance window](/host/set-maintenance-window)). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. - 2. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. - 3. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. - 4. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`, or re-run the backtester and read `days[].escrow_to_client_balance`. - 5. When you relist, rebuild the listing from the snapshot (`price_disk`, `min_chunk`, `end_date` or `duration`, `hidden_listing`, `sla_r_claim`, `sla_sigma_x`). If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + + `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key, or use the console notes above. Do not unlist until you have the terms. + 2. **Notify renters.** In the console: **Host → Machines → Settings → Machine Maintenances** (see [Set a maintenance window](/host/set-maintenance-window)). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. + 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. + 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. + 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. + 6. When you relist, rebuild the listing from the snapshot and your notes (`price_disk`, `min_chunk`, `end_date` or `duration`, `hidden_listing`, `sla_r_claim`, `sla_sigma_x`). If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing -On SLA rentals, compute pay and the SLA fee are released together as SLA earnings over several days. A single smaller release can be timing. By itself it is not proof of a credit. +On SLA rentals, compute pay and the SLA fee are released together as SLA earnings over several days. A single smaller release can reflect release timing, not a service credit. By itself it is not proof of a credit. After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). -For SLA contracts, `sla_earn` is the escrow released to you that day. It matches the backtester's `escrow_to_host_balance`. Releases are spread over time rather than paid out the same day, so an early or low day can be timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. +For SLA contracts, `sla_earn` is the escrow released to you that day. It matches the backtester's `escrow_to_host_balance`. Releases are spread over time rather than paid out the same day, so an early or low day can reflect release timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. @@ -720,7 +730,7 @@ When you poll the API, use **`per_machine[].sla_earn`** for a single machine. ** 2. Set the date range to include the UTC day you want to review. 3. Machine filtering is not available in the console. For one machine, use `vastai show earnings --machine_id ID`. 4. Look for the SLA settlement in the earnings breakdown. On an SLA rental, compute pay is released with the SLA fee (the same amount as `sla_earn` in the API), not as a separate GPU earnings line. -5. After downtime, compare several days with a normal week. A single smaller release can be timing, because escrow is released over time, not proof of a credit by itself. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. +5. After downtime, compare several days with a normal week. A single smaller release may only reflect timing, because escrow is released over several days. On its own, it does not prove a credit was paid. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. **If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). From 67334f78355f364d19b797d1ba28fe52539dccaa Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 18:52:25 -0700 Subject: [PATCH 164/250] docs(sla): address doc-review consensus (cycle 110) Use an exact UTC day for earnings checks, and note the offline window on machine listings. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 72ed8f89..6d4298c1 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -295,7 +295,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | -| Too many requests | HTTP 429. Search is about 10 requests per minute. Space rent calls about 5 seconds apart (OpenAPI `x-rate-limit` threshold 4.5, penalty 12). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Too many requests | HTTP 429. Search is about 10 requests per minute. Space rent calls about 5 seconds apart (the rent endpoint's rate-limit threshold is 4.5). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index e3a6215e..8c6d4e0d 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -278,7 +278,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** ## Fleet workflow -Optional, for API automation only. To check one machine, use the single-machine request above. +Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 8747c39b..43bd7ef8 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -707,7 +707,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m || echo "Snapshot is EMPTY: do not unlist yet" >&2 ``` - `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key, or use the console notes above. Do not unlist until you have the terms. + `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (that covers machines offline up to about 3 days), or use the console notes above. Do not unlist until you have the terms. 2. **Notify renters.** In the console: **Host → Machines → Settings → Machine Maintenances** (see [Set a maintenance window](/host/set-maintenance-window)). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. @@ -780,7 +780,13 @@ Weekly aggregates are window totals, not daily series — use a one-day range ab `GET /api/v0/users/me/machine-earnings/` returns SLA fields alongside compute earnings. The path user id is ignored; the account is the API key owner, so a **`billing_read`** key is enough (you do not need `user_read`). See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, one pull with `last_days=1` after UTC rollover is usually enough. +This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, pull one exact UTC day with `sday` and `eday` after UTC rollover. Do not use `last_days=1` for that job: it returns yesterday plus today so far. When a settled day stops changing is not documented; a later correction can change `sla_earn`. + +```bash +day=$(( $(date -u +%s) / 86400 - 1 )) +curl -s -H "Authorization: Bearer $VAST_API_KEY" \ + "https://console.vast.ai/api/v0/users/me/machine-earnings/?sday=$day&eday=$day" +``` **Automation pattern:** There is no host webhook for SLA settlement. One fleet call with `sday` and `eday` set to the same day index returns that UTC day for every machine in `per_machine[]`. Use `machid` only for a spot check. Do not use `per_day[].sla_earn` for a single machine. `last_days=1` is coarse: it covers yesterday and the current UTC day so far, not one settled day. From 9256e348bd231d3b0f696cfc29338e04570ddefc Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 19:03:50 -0700 Subject: [PATCH 165/250] docs(sla): address doc-review consensus (cycle 111) Describe the Charges sla row as net settlement, and define the blended reliability measure before it is used. Co-authored-by: Cursor --- api-reference/openapi.yaml | 6 +++--- .../openapi/yaml/show_instances.yaml | 2 +- api-reference/permissions.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 20 +++++++++---------- host/sla-offers.mdx | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index c9cadf88..f9c5ab4c 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8087,9 +8087,9 @@ paths: - name: limit in: query required: false - description: "Instances per page. Maximum 25. Omit or set \u2264 0 to use\ - \ the server default (currently 5). Prefer an explicit `limit` (for example\ - \ 25)." + description: Instances per page. Maximum 25. If omitted, the server starts + from 60 and then caps the page at 25. A non-positive limit is treated as + 5, then capped at 25. Prefer an explicit limit. schema: type: integer default: 5 diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index 9da55b8a..53b8c802 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -21,7 +21,7 @@ paths: - name: limit in: query required: false - description: Instances per page. Maximum 25. Omit or set ≤ 0 to use the server default (currently 5). Prefer an explicit `limit` (for example 25). + description: Instances per page. Maximum 25. If omitted, the server starts from 60 and then caps the page at 25. A non-positive limit is treated as 5, then capped at 25. Prefer an explicit limit. schema: type: integer default: 5 diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index e037cbf8..0c052dfe 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -121,10 +121,10 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if | Rent with an SLA | `instance_write` | Console **RENT** | | Verify `target_reliability` | `instance_read` | **Instances** | -**Service credits:** Use the web console (**Account → Billing**) to view SLA credits. `GET /api/v0/charges/` can include `items[].type` `sla` (description **SLA Fee**) on SLA rentals, in addition to `gpu`, `disk`, `bwd`, and `bwu`. That row is the SLA fee for the period, not an itemized service credit. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. +**Service credits:** An itemized **Service Credit** line appears only in the web console (**Account → Billing**). `GET /api/v0/charges/` can include `results[].items[]` rows with `type: "sla"` (description still **SLA Fee**). Each row is the **net** SLA settlement for settled days in the window: SLA fee minus any service credit. On a day with a credit the amount is smaller and can be negative. The row is omitted until the last day in the window has settled. Follow `next_token` until it is empty. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. -Do not use the Charges API alone to reconcile service credits. The `sla` row is the fee, not the credit. +Do not use the Charges API alone to reconcile service credits. The `sla` row is a net amount, not an itemized credit, and it is missing until the window has settled. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 6d4298c1..b2c71294 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -15,15 +15,15 @@ An SLA is an optional reliability promise on an **on-demand** GPU rental. You do 1. The **host** states a **reliability commitment**: how often they expect the machine to be up. 2. **You** choose a **reliability target**: how much uptime you want. A higher target costs more. 3. You pay an **SLA fee** (a service level fee) on top of the GPU price. -4. Each day, Vast checks how long your instance was actually up. -5. If the blended measure met your reliability target, the host keeps the SLA fee. "Met" uses Vast's blended reliability measure (recent and longer-term uptime), not that day's raw uptime alone. A day whose raw uptime is at or slightly above your target can still produce a partial credit if the blended measure falls below it. -6. If the blended measure fell below your reliability target, you receive a **service credit**. That credit can be larger than the SLA fee you paid that day. +4. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. +5. If that blended measure met your reliability target, no credit is owed. If it fell short, you receive a **service credit**. Because longer-term uptime is included, a single bad day after a stretch of good uptime can produce a smaller credit than that day's raw uptime suggests. The reverse is also true: raw uptime at or slightly above your target can still produce a partial credit when the blended measure is below it. +6. That credit can be larger than the SLA fee you paid that day. A few things people mix up: - The **reliability score** on an offer card is a separate marketplace signal. It is not your SLA. - The GPU bill does **not** stop during an outage. SLA pays you back later as a credit, usually after the next UTC midnight. -- A search filter does **not** turn on an SLA. You have to set a reliability target when you rent, in the web console or with the API. The CLI cannot turn SLA on today. +- Filtering for SLA offers (`has_sla`, SLA-enabled) or quoting from the CLI/API does **not** turn on an SLA. Setting **Reliability target** in the console Search filters and then clicking **RENT**, or sending `target_reliability` on REST rent, does. The CLI cannot turn SLA on. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. - If the price breakdown has **no SLA Fee line**, you do not have an SLA. In **Account → Billing** the same charge appears as **SLA Fee**, and credits as **Service Credit**. In API responses the hourly amount is `slaPremiumPerHour`. @@ -198,7 +198,7 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ | Search / quote an SLA | Yes | Yes (`POST /api/v0/bundles/`) | | Enable an SLA at rent | Yes | Yes (`target_reliability` on `PUT /api/v0/asks/{id}/`) | | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | -| SLA service credits | **Account → Billing** | Not in `GET /api/v0/charges/`, `GET /api/v1/invoices/`, or client webhooks | +| SLA service credits | **Account → Billing** (itemized **Service Credit**) | Charges `results[].items[].type` `sla` is the net of fee minus credit, not an itemized credit. Not in invoices or client webhooks. | **Rent body (SLA):** Among SLA-related fields, send only `target_reliability` (not `sla_r_claim` / `sla_r_target`). Still include `image` or `template_hash_id` and a `disk` that matches your search quote. @@ -279,10 +279,10 @@ curl -G "https://console.vast.ai/api/v1/instances/" \ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row. For the SLA fee: if the instance is not yet **running**, use `search.slaPremiumPerHour` (search-context pricing); once **running**, also check `instance.slaPremiumPerHour`. A missing `instance.slaPremiumPerHour` before startup is not a failed SLA rent. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, confirm you used `new_contract` (not the offer id), then retry after a short delay, no more than about once per second (`show_instances` `x-rate-limit` threshold `1.0`). Use `after_token` paging only when listing without an `id` filter. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). -- **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). The server default `limit` can be as low as **5** (maximum **25**). +- **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). If you omit `limit`, the server returns at most **25** rows. A non-positive `limit` is treated as 5, then capped at 25. - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. -**Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing**. `GET /api/v0/charges/` does not list those credits. +**Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing** for the itemized **Service Credit**. On `GET /api/v0/charges/`, `results[].items[]` with `type: "sla"` is the net of the SLA fee minus any credit (the description still says **SLA Fee**). It can be smaller or negative, and it is omitted until the last day in the window has settled. Page with `next_token`. **Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour`. Show-instances uses OpenAPI threshold `1.0` (about one request per second). @@ -295,7 +295,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | -| Too many requests | HTTP 429. Search is about 10 requests per minute. Space rent calls about 5 seconds apart (the rent endpoint's rate-limit threshold is 4.5). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Too many requests | HTTP 429. Treat about 10 search requests per minute as a safe floor (the server allows short bursts above that). Space rent calls about 5 seconds apart (the rent endpoint's rate-limit threshold is 4.5). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | @@ -359,7 +359,7 @@ Production settlement uses the multi-window reliability blend described above, n ### Settlement timing - Settlement runs **once per day** for the previous billing day (UTC). -- Service credits post to your **account balance**. View them under **Account → Billing** in the console. They do **not** appear as `items[].type` on `GET /api/v0/charges/`. Do not use the Charges API or `vastai show invoices-v1 --charges` to reconcile SLA credits. +- Service credits post to your **account balance**. View the itemized **Service Credit** under **Account → Billing**. Do not treat a Charges `type: "sla"` row as that line: it is the net of fee minus credit. Do not use invoices to reconcile SLA credits. - When your contract ends, any remaining unsettled days are resolved at close. ## If your instance goes down @@ -436,7 +436,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta **Console:** After UTC settlement, open **Account → Billing** and look for **Service Credit** — not in the instance price panel. Credits are not available via the Charges API, invoices, or billing exports today. -**API integrators:** Prefer **Account → Billing** for service credit reconciliation. `GET /api/v0/charges/` can return `type: "sla"` with description **SLA Fee**. That amount is the SLA fee for the period, not an itemized service credit. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). +**API integrators:** Prefer **Account → Billing** for an itemized **Service Credit**. `GET /api/v0/charges/` → `results[].items[]` with `type: "sla"` (description **SLA Fee**) is the net SLA settlement for the window: fee minus credit. The amount can be negative. The row is omitted until the window's last day has settled; follow `next_token`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). ## Related documentation diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 43bd7ef8..31638356 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -88,8 +88,8 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. If the blended measure met their reliability target, you keep the SLA fee. "Met" uses Vast's blended reliability measure (recent and longer-term uptime), not that day's raw uptime alone. A day whose raw uptime is at or slightly above the target can still produce a partial credit if the blended measure falls below it. When the blended measure meets the target, no credit is paid. -7. If the blended measure fell below their reliability target, the renter receives a **service credit** from your earnings. One bad day can cost more than many days of fees. +6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. If it met the renter's target, you keep the SLA fee and no credit is paid. If it fell short, the renter receives a **service credit** from your earnings. A single bad day after a stretch of good uptime can owe less than that day's raw uptime suggests. Raw uptime at or slightly above the target can still owe a partial credit when the blend is below it. +7. One bad day can cost more than many days of fees. What this is not: From 50f8dc85654c61f710572c4d36fc7e0b80bbedae Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 19:10:39 -0700 Subject: [PATCH 166/250] docs(sla): address doc-review consensus (cycle 112) Align Charges credit wording with the net sla row, and warn that a later offer end date extends SLA rentals. Co-authored-by: Cursor --- api-reference/permissions.mdx | 12 +++++++++--- guides/instances/choosing/sla-coverage.mdx | 10 +++++----- host/hosting-overview.mdx | 4 ++-- host/sla-offers.mdx | 6 +++--- snippets/host/cli/list-machine.mdx | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 0c052dfe..ea71217f 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -95,7 +95,7 @@ You can create scoped keys using: Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. SLA credits appear only in the console. +**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. The itemized **Service Credit** line is only in the console. Charges `type: "sla"` is the net of fee minus credit. - Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. @@ -121,7 +121,13 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if | Rent with an SLA | `instance_write` | Console **RENT** | | Verify `target_reliability` | `instance_read` | **Instances** | -**Service credits:** An itemized **Service Credit** line appears only in the web console (**Account → Billing**). `GET /api/v0/charges/` can include `results[].items[]` rows with `type: "sla"` (description still **SLA Fee**). Each row is the **net** SLA settlement for settled days in the window: SLA fee minus any service credit. On a day with a credit the amount is smaller and can be negative. The row is omitted until the last day in the window has settled. Follow `next_token` until it is empty. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. +**Service credits:** An itemized **Service Credit** line appears only in the web console (**Account → Billing**). `GET /api/v0/charges/` requires `select_filters` with both `day.gte` and `day.lte` (unix seconds, UTC). A call without that range returns HTTP 400. The response can include `results[].items[]` rows with `type: "sla"` (description still **SLA Fee**). Each row is the **net** SLA settlement for settled days in the window: SLA fee minus any service credit. On a day with a credit the amount is smaller and can be negative. The row is omitted until the last day in the window has settled. Page by sending `next_token` as `after_token`. Stop when `next_token` is `null`. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. + +```bash +curl -G "https://console.vast.ai/api/v0/charges/" \ + -H "Authorization: Bearer $VAST_API_KEY" \ + --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1769903999}}' +``` Do not use the Charges API alone to reconcile service credits. The `sla` row is a net amount, not an itemized credit, and it is missing until the window has settled. @@ -131,7 +137,7 @@ Do not use the Charges API alone to reconcile service credits. The `sla` row is **Host — list, backtest, and earnings.** -Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` alone lists and updates an offer. It does not backtest or read earnings. Add `machine_read` and `billing_read` for those tasks. +Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` can change a listing but cannot read current values. Pair it with `machine_read` so a script can read, then send a full body, because omitted fields reset. It does not backtest or read earnings. Add `billing_read` for earnings. For cron, prefer a `billing_read` key for monitoring and a separate `machine_write` + `machine_read` key for listing changes. **Workflow summary:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b2c71294..4f3de6aa 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -186,7 +186,7 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d -Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. SLA service credits appear only in the web console billing UI—not in Charges, Invoices, or credit webhooks. +Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. Service credits are not itemized in any API. In Charges, `type: "sla"` rows are the net of the SLA fee minus any credit (they can be negative) and appear only after the window settles. The itemized **Service Credit** line is only in the web console. Invoices and credit webhooks do not itemize it. @@ -282,7 +282,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). If you omit `limit`, the server returns at most **25** rows. A non-positive `limit` is treated as 5, then capped at 25. - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. -**Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing** for the itemized **Service Credit**. On `GET /api/v0/charges/`, `results[].items[]` with `type: "sla"` is the net of the SLA fee minus any credit (the description still says **SLA Fee**). It can be smaller or negative, and it is omitted until the last day in the window has settled. Page with `next_token`. +**Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing** for the itemized **Service Credit**. `GET /api/v0/charges/` requires `select_filters` with `day.gte` and `day.lte` (unix seconds). `results[].items[]` with `type: "sla"` is the net of the SLA fee minus any credit (the description still says **SLA Fee**). It can be smaller or negative, and it is omitted until the last day in the window has settled. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. **Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour`. Show-instances uses OpenAPI threshold `1.0` (about one request per second). @@ -295,7 +295,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | -| Too many requests | HTTP 429. Treat about 10 search requests per minute as a safe floor (the server allows short bursts above that). Space rent calls about 5 seconds apart (the rent endpoint's rate-limit threshold is 4.5). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Too many requests | HTTP 429. Stay at or below about 10 search requests per minute per IP (Search Offers `x-rate-limit`). Back off on HTTP 429 before sending more. Space rent calls about 5 seconds apart (the rent endpoint's rate-limit threshold is 4.5). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | @@ -434,9 +434,9 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing** and look for **Service Credit** — not in the instance price panel. Credits are not available via the Charges API, invoices, or billing exports today. +**Console:** After UTC settlement, open **Account → Billing** and look for **Service Credit** — not in the instance price panel. Service credits are not itemized in the Charges API, invoices, or billing exports. A Charges `type: "sla"` row is the net of fee minus credit, not that line. -**API integrators:** Prefer **Account → Billing** for an itemized **Service Credit**. `GET /api/v0/charges/` → `results[].items[]` with `type: "sla"` (description **SLA Fee**) is the net SLA settlement for the window: fee minus credit. The amount can be negative. The row is omitted until the window's last day has settled; follow `next_token`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). +**API integrators:** Prefer **Account → Billing** for an itemized **Service Credit**. `GET /api/v0/charges/` → `results[].items[]` with `type: "sla"` (description **SLA Fee**) is the net SLA settlement for the window: fee minus credit. The amount can be negative. The row is omitted until the window's last day has settled. The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). ## Related documentation diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 73374d1a..c0b85245 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -209,7 +209,7 @@ There are two supported ways to test your own machine. If you want to use the we The preferred method of testing your own machine is to run the [CLI](https://cloud.vast.ai/cli/). For Windows users, we suggest setting up [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) which will require you to install Ubuntu on your Windows machine and change your bios settings to allow virtualization. Then you can start an Ubuntu terminal and run the CLI. -To rent your own machine you will need to first search the offers with your machine ID to find the ID and then create an instance using that ID. The show machine command will show all your connected machines. +To rent your own machine you will need to first search the offers with your machine ID to find the ID and then create an instance using that ID. Use the **host** account key for `show machines` and a separate **client** account key for `search offers` and `create instance` (`--api-key`). Renting with the host key is rejected. The show machine command will show all your connected machines. ```text Text ./vastai show machines @@ -249,7 +249,7 @@ You can then look at your [instance tab](https://cloud.vast.ai/instances/) to ma Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. -Unlisting the offer prevents new rentals but does not end existing ones. If you have active contracts, you can set the offer end date to match the latest rental end date so new clients rent instances that end together. Once that date is reached, unlist and perform maintenance. +Unlisting the offer prevents new rentals but does not end existing ones. If you have active contracts, you can set the offer end date to match the latest rental end date so new clients rent instances that end together. Once that date is reached, unlist and perform maintenance. Setting the offer end date later extends every active rental that ends earlier, and SLA rentals keep their credit exposure for the extra time. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). If you host SLA rentals, unlist instead of moving the end date later. Use these paths in order: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 31638356..b604e283 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -195,7 +195,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r **Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). -**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA fees (more competitive `dph_total`). **Wider confidence** (console label **Wide**) → higher client SLA fees. Confidence does **not** change the credit formula when a target is missed — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. +**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA fees (more competitive `dph_total`) and less fee income to offset a miss. **Wider confidence** (console label **Wide**) → higher client SLA fees, which is a cushion, not a smaller credit. For a new or volatile machine, start with **Wide**, then move to **Normal** once uptime is stable. Confidence does **not** change the credit formula when a target is missed — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. ### Validation rules @@ -234,7 +234,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. -4. Set your **reliability commitment** (the console control is **Claim**; the API field is `sla_r_claim`). Renters see it as expected reliability on the offer. Set **Confidence** too. For your first listing, choose **Normal** (`sla_sigma_x ≈ 0.5`) unless your uptime history is volatile — see [Confidence values](#confidence-values) for risk tradeoffs. +4. Set your **reliability commitment** (the console control is **Claim**; the API field is `sla_r_claim`). Renters see it as expected reliability on the offer. Set **Confidence** too. For a new or volatile machine, start with **Wide**. Wider confidence charges a higher SLA fee, which is a cushion against credits; it does not reduce what you owe when a day misses the target. Move to **Normal** (`sla_sigma_x ≈ 0.5`) once uptime is stable. See [Confidence values](#confidence-values). 5. Save and confirm the SLA fee preview before listing. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. @@ -371,7 +371,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge -Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. Re-list only machines whose rentals already end on or after the offer end date, or accept the extension. After a live run, read `upd_contracts` in the output. +Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. Re-list only machines whose rentals already end on or after the offer end date, or accept the extension. `show machines` does not list each contract's end date, and `DRY_RUN` does not either, so you cannot check this beforehand. After a live run, read `upd_contracts` in the output. Use this loop to republish SLA terms across a fleet, for example after a daemon update. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 56e6c748..1216c71b 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. Update hidden SLA listings through REST. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets storage price to `-s` (default $0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. ## Usage From 10d6cf00e281149bc9ae11931789a5cc58bb3e3a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 19:19:41 -0700 Subject: [PATCH 167/250] docs(sla): address doc-review consensus (cycle 113) Document the rent 404 race, and stop describing CLI prices as SLA quotes. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 4 ++-- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 16 ++++++++-------- host/hosting-overview.mdx | 6 +++--- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 8 ++++---- snippets/host/cli/list-machine.mdx | 2 +- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index ea71217f..430fce7c 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -95,7 +95,7 @@ You can create scoped keys using: Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. The itemized **Service Credit** line is only in the console. Charges `type: "sla"` is the net of fee minus credit. +**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. The itemized **Service Credit** line is only in the console. Charges `type: "sla"` is the SLA fee minus any service credit. - Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 12e14620..3b0fa2aa 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -11,7 +11,7 @@ The CLI can find SLA offers but cannot price them. To see the SLA fee in `dph_to **If you only use the CLI today** -1. Use `search offers` to compare quotes (SLA filters are optional). +1. Use `search offers` to find offers (SLA filters are optional). The CLI price does not include the SLA fee. 2. To rent with SLA, open console Search, set **Reliability target** in the **left Search filters**, confirm an **SLA fee** line, then **RENT**—or follow [API automation](/guides/instances/choosing/sla-coverage#api-automation). `vastai create instance` cannot set `target_reliability`. ## Usage @@ -57,7 +57,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] - Maximum number of offers to return. Prefer an explicit limit when comparing SLA-inclusive `dph_total` results; combine with `--order` / `-o` as needed. + Maximum number of offers to return. Prefer an explicit limit when comparing results. CLI `dph_total` never includes the SLA fee. Combine with `--order` / `-o` as needed. diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 45114554..51821607 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA Fee** line in the price breakdown. An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -CLI and API search only **quote** SLA pricing—they do not turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA Fee** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). +The console and REST search quote SLA-inclusive prices. The CLI can only find SLA offers; its `dph_total` excludes the SLA fee. None of them turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA Fee** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 4f3de6aa..c7c7572f 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -23,7 +23,7 @@ A few things people mix up: - The **reliability score** on an offer card is a separate marketplace signal. It is not your SLA. - The GPU bill does **not** stop during an outage. SLA pays you back later as a credit, usually after the next UTC midnight. -- Filtering for SLA offers (`has_sla`, SLA-enabled) or quoting from the CLI/API does **not** turn on an SLA. Setting **Reliability target** in the console Search filters and then clicking **RENT**, or sending `target_reliability` on REST rent, does. The CLI cannot turn SLA on. +- Filtering for SLA offers (`has_sla`, SLA-enabled), or a CLI or API search, does **not** turn on an SLA. Setting **Reliability target** in the console Search filters and then clicking **RENT**, or sending `target_reliability` on REST rent, does. The CLI cannot turn SLA on. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. - If the price breakdown has **no SLA Fee line**, you do not have an SLA. In **Account → Billing** the same charge appears as **SLA Fee**, and credits as **Service Credit**. In API responses the hourly amount is `slaPremiumPerHour`. @@ -90,7 +90,7 @@ Quoted hourly cost with SLA in search (`dph_total`): dph_total ≈ GPU + storage + SLA fee ``` -Bandwidth is billed separately from usage (`inet_*` rates) and is **not** included in `dph_total`. +Bandwidth is billed separately, based on usage (`inet_*` rates), and is **not** included in `dph_total`. | Factor | What it means for you | | --- | --- | @@ -186,7 +186,7 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d -Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. Service credits are not itemized in any API. In Charges, `type: "sla"` rows are the net of the SLA fee minus any credit (they can be negative) and appear only after the window settles. The itemized **Service Credit** line is only in the web console. Invoices and credit webhooks do not itemize it. +Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. Service credits are not itemized in any API. In Charges, `type: "sla"` rows are the SLA fee minus any service credit (they can be negative) and appear only after the window settles. The itemized **Service Credit** line is only in the web console. Invoices and credit webhooks do not itemize it. @@ -198,7 +198,7 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ | Search / quote an SLA | Yes | Yes (`POST /api/v0/bundles/`) | | Enable an SLA at rent | Yes | Yes (`target_reliability` on `PUT /api/v0/asks/{id}/`) | | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | -| SLA service credits | **Account → Billing** (itemized **Service Credit**) | Charges `results[].items[].type` `sla` is the net of fee minus credit, not an itemized credit. Not in invoices or client webhooks. | +| SLA service credits | **Account → Billing** (itemized **Service Credit**) | Charges `results[].items[].type` `sla` is the SLA fee minus any service credit, not an itemized credit. Not in invoices or client webhooks. | **Rent body (SLA):** Among SLA-related fields, send only `target_reliability` (not `sla_r_claim` / `sla_r_target`). Still include `image` or `template_hash_id` and a `disk` that matches your search quote. @@ -282,7 +282,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). If you omit `limit`, the server returns at most **25** rows. A non-positive `limit` is treated as 5, then capped at 25. - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. -**Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing** for the itemized **Service Credit**. `GET /api/v0/charges/` requires `select_filters` with `day.gte` and `day.lte` (unix seconds). `results[].items[]` with `type: "sla"` is the net of the SLA fee minus any credit (the description still says **SLA Fee**). It can be smaller or negative, and it is omitted until the last day in the window has settled. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. +**Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing** for the itemized **Service Credit**. `GET /api/v0/charges/` requires `select_filters` with `day.gte` and `day.lte` (unix seconds). `results[].items[]` with `type: "sla"` is the SLA fee minus any service credit (the description still says **SLA Fee**). It can be smaller or negative, and it is omitted until the last day in the window has settled. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. **Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour`. Show-instances uses OpenAPI threshold `1.0` (about one request per second). @@ -291,7 +291,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Target outside `[0, 1)` (negative, or 1 or above) | HTTP 400 `invalid_args` ("target reliability must be greater than or equal to 0 and less than 1") | SLA requires `0 < target_reliability < 1`. Sending `0` or omitting the field rents **without** an SLA (HTTP 200, no error). | | Offer has no SLA, target is above the host commitment, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | | SLA not enabled for the account or region | HTTP 403 `sla_disabled` | Contact support | -| Offer no longer exists | HTTP 400 `invalid_args` (`no_such_ask`; `msg` may contain `error 404/3603`) or HTTP 410 | Re-search and use a fresh offer ID. The HTTP status for a missing offer is 400, not 404. | +| Offer no longer exists | HTTP 400 `invalid_args` (`msg` may contain `error 404/3603`), HTTP 404 `no_such_ask` (`msg` may contain `error 404/3659` if the offer was taken mid-request), or HTTP 410 | Re-search and use a fresh offer ID. Do not retry the same ID. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | @@ -359,7 +359,7 @@ Production settlement uses the multi-window reliability blend described above, n ### Settlement timing - Settlement runs **once per day** for the previous billing day (UTC). -- Service credits post to your **account balance**. View the itemized **Service Credit** under **Account → Billing**. Do not treat a Charges `type: "sla"` row as that line: it is the net of fee minus credit. Do not use invoices to reconcile SLA credits. +- Service credits post to your **account balance**. View the itemized **Service Credit** under **Account → Billing**. Do not treat a Charges `type: "sla"` row as that line: it is the SLA fee minus any service credit. Do not use invoices to reconcile SLA credits. - When your contract ends, any remaining unsettled days are resolved at close. ## If your instance goes down @@ -434,7 +434,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing** and look for **Service Credit** — not in the instance price panel. Service credits are not itemized in the Charges API, invoices, or billing exports. A Charges `type: "sla"` row is the net of fee minus credit, not that line. +**Console:** After UTC settlement, open **Account → Billing** and look for **Service Credit** — not in the instance price panel. Service credits are not itemized in the Charges API, invoices, or billing exports. A Charges `type: "sla"` row is the SLA fee minus any service credit, not that line. **API integrators:** Prefer **Account → Billing** for an itemized **Service Credit**. `GET /api/v0/charges/` → `results[].items[]` with `type: "sla"` (description **SLA Fee**) is the net SLA settlement for the window: fee minus credit. The amount can be negative. The row is omitted until the window's last day has settled. The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index c0b85245..44699fae 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -90,7 +90,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Changing the price** does not change the rate on any existing rental contract - **Shortening** the offer end date limits the commitment window for new clients, but does not shorten any existing rental end date -- **Extending** the offer end date allows new clients to rent for a longer period +- **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts will be created at the new terms, while old rental contracts continue at their original terms. This means a single machine may have active rental contracts at different prices and different rental end dates. @@ -218,7 +218,7 @@ To rent your own machine you will need to first search the offers with your mach Then for each machine id you will need to find the available **offer/ask IDs** (not running instance IDs). ```text Text -./vastai search offers 'machine_id=12345 verified=any' +./vastai search offers 'machine_id=12345 verified=any' --api-key "$CLIENT_API_KEY" ``` Replace 12345 with your actual machine ID in question. You can see the number of available listings as well as information about the machine. This is the fastest way to also see all the offers listed for a given machine. The website GUI stacks similar offers and so it is not easy to see all the listings for a given machine. That is not a problem for the CLI. @@ -226,7 +226,7 @@ Replace 12345 with your actual machine ID in question. You can see the number of Take the **offer/ask ID** from the first column of search results and use it with `create instance`. This creates a **test rental billed to your separate client account** like any other rental (it is not free). Host earnings offset client spend only after rentals settle. This example loads the latest pytorch image along with both jupyter and ssh direct launch modes. ```text Text -vastai create instance --image pytorch/pytorch:latest --jupyter --direct --env '-e TZ=PDT -p 22:22 -p 8080:8080' +vastai create instance --api-key "$CLIENT_API_KEY" --image pytorch/pytorch:latest --jupyter --direct --env '-e TZ=PDT -p 22:22 -p 8080:8080' ``` Use `./vastai` instead of `vastai` when running from the install directory. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 8c6d4e0d..24149ef4 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -53,7 +53,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). **Simulation limits** -- The whole machine is replayed as one contract. Live settlement runs per rental contract, so several concurrent SLA renters on a sliced machine can produce more credits on one day than the simulation shows. Pair this output with [SLA and GPU slicing](/host/sla-offers#sla-and-gpu-slicing). +- The replay treats all historical compute as one SLA contract, so it overstates fees and credits when few renters chose SLA. The whole machine is replayed as one contract. Live settlement runs per rental contract, so several concurrent SLA renters on a sliced machine can produce more credits on one day than the simulation shows. Pair this output with [SLA and GPU slicing](/host/sla-offers#sla-and-gpu-slicing). - For renter-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or a REST search with a realistic `target_reliability` (the CLI cannot send `target_reliability` today). - How recent versus long-term uptime is weighted is set automatically from the renter target. It is not a host setting; the value used is echoed in `params.beta`. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index b604e283..48c8bf11 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -374,7 +374,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. Re-list only machines whose rentals already end on or after the offer end date, or accept the extension. `show machines` does not list each contract's end date, and `DRY_RUN` does not either, so you cannot check this beforehand. After a live run, read `upd_contracts` in the output. -Use this loop to republish SLA terms across a fleet, for example after a daemon update. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. +Run this only when an SLA listing is missing from search after a daemon update even though **Set Pricing** still shows SLA. Healthy listings do not need a re-list, and every re-list can extend shorter active contracts. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. `show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. @@ -697,7 +697,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **Severe outage (active SLA contracts):** 1. **Save your current terms before you unlist.** After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, and SLA terms. The snapshot does not include confidence (`sla_sigma_x`; only the `sla_confidence` label) or hidden status (`hidden_listing`). Write both down either way. - **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, and Confidence (Tight, Normal, or Wide). + **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, and Confidence (Tight, Normal, or Wide). ```bash vastai show machines --raw --api-key "$VAST_API_KEY" \ @@ -712,7 +712,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. When you relist, rebuild the listing from the snapshot and your notes (`price_disk`, `min_chunk`, `end_date` or `duration`, `hidden_listing`, `sla_r_claim`, `sla_sigma_x`). If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. When you relist, use the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), and Confidence (`sla_sigma_x`). Send `sla_sigma_x` explicitly; a new ask otherwise defaults to 0.5. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing @@ -794,7 +794,7 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. To cross-check the backtester, compare `sla_earn` with that day's `escrow_to_host_balance`. Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. - **Fleet, exact UTC day (one call):** omit `machid` and set `sday` and `eday` to the same day index. Read `per_machine[].sla_earn`. - **Recent window (`last_days`, coarse):** one request without `machid` returns all machines in `per_machine[]`. `last_days=1` spans yesterday and today-so-far. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 1216c71b..29c11c2b 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets storage price to `-s` (default $0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. ## Usage From a7f83376234ef05bb0c1e62dc81e61d62059d4d6 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 19:29:07 -0700 Subject: [PATCH 168/250] docs(sla): address doc-review consensus (cycle 114) A fee-raising listing update does not keep SLA rentals from being extended later, and a host key can rent its own offers. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 4 +++- guides/reference/billing.mdx | 2 +- guides/reference/faq/billing.mdx | 2 +- host/hosting-overview.mdx | 11 +++++++---- host/sla-offers.mdx | 11 ++++++----- snippets/host/cli/list-machine.mdx | 2 +- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c7c7572f..24e34252 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -297,7 +297,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | | Too many requests | HTTP 429. Stay at or below about 10 search requests per minute per IP (Search Offers `x-rate-limit`). Back off on HTTP 429 before sending more. Space rent calls about 5 seconds apart (the rent endpoint's rate-limit threshold is 4.5). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | -| Forbidden / wrong account | HTTP 400 `invalid_args`. The message text includes `error 403/3586` and "Hosts can only rent their own machines." The HTTP status is 400, not 403. | Rent with a **renter** account API key, not the host listing key (see [Hosting Overview](/host/hosting-overview) self-test note). | +| Forbidden / wrong account | HTTP 400 `invalid_args`. The message includes `error 403/3586` ("Hosts can only rent their own machines"). The HTTP status is 400, not 403. A host-only key gets this for every offer that is not on its own machines, including a missing offer. | Switch to a renter account key, then re-search (see [Hosting Overview](/host/hosting-overview) self-test note). | | Channel | Default storage | Field | Units (label) | | --- | --- | --- | --- | @@ -324,6 +324,8 @@ When you rent an SLA-backed offer **with a target set**: Billing continues during downtime. You are still charged for **compute, storage, and the SLA fee** while the contract exists and the instance is unavailable. Leaving a broken instance running continues those charges until you destroy it. +**This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and the service credit is the compensation for that downtime. + **Stop vs destroy:** Stopping pauses compute but storage and contract charges can continue. **Destroying the instance** ends future daily charges; final SLA settlement still posts when the contract closes. If you abandon a failed host, destroy only after saving any data you need. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index dacbe58d..9fa29dc3 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -82,7 +82,7 @@ You are charged the base active rental cost for every second your instance is in You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. +You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals are billed for intended compute during downtime and compensated with service credits. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). To see a pricing breakdown on your current instances within your Instance page in the console or from offers on the Search page you can hover over the price to see pricing details. diff --git a/guides/reference/faq/billing.mdx b/guides/reference/faq/billing.mdx index 96804ac8..64656c1b 100644 --- a/guides/reference/faq/billing.mdx +++ b/guides/reference/faq/billing.mdx @@ -33,7 +33,7 @@ You are charged the storage cost (which depends on the size of your storage allo Stopping an instance does not avoid storage costs. You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. +You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals are billed for intended compute during downtime and compensated with service credits. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). ### What is the billing frequency? diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 44699fae..0d1a9730 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -193,7 +193,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. Moving the end date later extends every shorter active rental, including its SLA exposure, to the new date. If the request that moves the end date later also changes SLA terms in a way that would raise an existing contract's SLA fee (a lower commitment, wider confidence, or turning SLA off), that contract is not extended. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. Moving the end date later extends every shorter active rental, including its SLA exposure, to the new date. If that request would also raise an existing contract's SLA fee, the immediate response skips that contract. A background job extends it shortly afterward anyway, under its original SLA terms. Do not move the end date later if you need to avoid that. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). If you have raised the pricing, you cannot extend the current rental contracts. @@ -209,7 +209,7 @@ There are two supported ways to test your own machine. If you want to use the we The preferred method of testing your own machine is to run the [CLI](https://cloud.vast.ai/cli/). For Windows users, we suggest setting up [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) which will require you to install Ubuntu on your Windows machine and change your bios settings to allow virtualization. Then you can start an Ubuntu terminal and run the CLI. -To rent your own machine you will need to first search the offers with your machine ID to find the ID and then create an instance using that ID. Use the **host** account key for `show machines` and a separate **client** account key for `search offers` and `create instance` (`--api-key`). Renting with the host key is rejected. The show machine command will show all your connected machines. +To rent your own machine you will need to first search the offers with your machine ID to find the ID and then create an instance using that ID. Use the **host** account key for `show machines` and a separate **client** account key for `search offers` and `create instance` (`--api-key`). A host key can rent offers on your own machines. Every other offer returns HTTP 400 `invalid_args` (`error 403/3586`). Use the client key so the test matches a real renter. The show machine command will show all your connected machines. ```text Text ./vastai show machines @@ -245,11 +245,14 @@ You can then look at your [instance tab](https://cloud.vast.ai/instances/) to ma ## Maintenance -**Prerequisite:** Notify renters from the console ([Set a maintenance window](/host/set-maintenance-window)) or with the CLI/REST. Use one path per window. +**If renters are active:** notify them from the console ([Set a maintenance window](/host/set-maintenance-window)) or with the CLI/REST before downtime. Use one path per window. Remember that a single machine may have multiple active rental contracts from different clients, each with its own rental end date. All rental contracts must be honored. -Unlisting the offer prevents new rentals but does not end existing ones. If you have active contracts, you can set the offer end date to match the latest rental end date so new clients rent instances that end together. Once that date is reached, unlist and perform maintenance. Setting the offer end date later extends every active rental that ends earlier, and SLA rentals keep their credit exposure for the extra time. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). If you host SLA rentals, unlist instead of moving the end date later. +Unlisting the offer prevents new rentals but does not end existing ones. + +- **No SLA rentals:** you can set the offer end date to the latest rental end date so new rentals end together, then unlist and maintain. +- **SLA rentals:** unlist instead. Moving the end date later extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 48c8bf11..6135152d 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -39,7 +39,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**—listing not required yet). -2. Create and fund a separate **client** account for later self-test (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine) account setup)—do **not** rent your machine yet; listing comes in step 8. +2. Publish once **without** SLA (leave Claim at `0`) and test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. @@ -202,7 +202,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.99999**. Exactly `1.0` is rejected. -- When the reliability commitment is positive, `sla_sigma_x` must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. On an existing listing, send it explicitly the first time you enable SLA. If a value is already stored, omitting it keeps that value. +- If you send `sla_sigma_x`, it must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. If you enable SLA on an existing ask without sending it, the request is accepted and `show machines` can report `sla_confidence: null`. If a value is already stored, omitting it keeps that value. Send it explicitly the first time you enable SLA. - Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. @@ -221,7 +221,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. If the request that moves `end_date` later also changes SLA terms in a way that would raise an existing contract's SLA fee (a lower commitment, wider confidence, or `sla_r_claim` set to `0`), that contract is not extended, and the response does not say so. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. If the same request also raises an existing contract's SLA fee (a lower commitment, wider confidence, or `sla_r_claim` set to `0`), the immediate response skips that contract. A background job extends it shortly afterward anyway, under its original SLA terms. The only reliable way to avoid extending SLA rentals is to not move `end_date` later, or to unlist. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -343,10 +343,11 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - `price_gpu` is kept if omitted. - `price_disk` resets to **$0.10/GB/month** if omitted or `null`. -- `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing). +- `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing). While `duration` is set, the offer end date moves forward on its own, and active SLA rentals are extended with it. Credit exposure continues for as long as that listing stays live. - `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. - `min_chunk` defaults to **1** when offers are created or re-created (first publish, or relisting after an unlist). On an already-listed machine, omitting it does not change the current minimum. Still send `listed_min_gpu_count` so a later relist does not slice the machine by accident. - `vol_size` omitted on a machine with no volume offer creates one sized at half the free disk. Send `"vol_size": 0` to keep that from happening. `0` does not delete a volume offer that already exists. +- On a **new** ask (first publish, or a new offer after unlist), omitted `price_inetu` and `price_inetd` become `0` (free bandwidth) and omitted `credit_discount_max` becomes `0.4`. Updating an existing ask keeps those values when they are omitted. Send `listed_inet_up_cost`, `listed_inet_down_cost`, and `credit_discount_max` when you create the offer. - Send **either** `duration` (integer seconds; a float such as `2592000.0` returns 400 `Invalid duration`) **or** `end_date`, never both. Sending both returns `400` `Cannot set both duration and end_date`. Always read the current listing and send `price_disk` plus either `duration` or `end_date`. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. @@ -707,7 +708,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m || echo "Snapshot is EMPTY: do not unlist yet" >&2 ``` - `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (that covers machines offline up to about 3 days), or use the console notes above. Do not unlist until you have the terms. + `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If it is still empty, use the console notes above. Do not unlist until you have the terms. 2. **Notify renters.** In the console: **Host → Machines → Settings → Machine Maintenances** (see [Set a maintenance window](/host/set-maintenance-window)). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 29c11c2b..32af5378 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -53,7 +53,7 @@ vastai list machine ID [options] - Updates end_date daily to be duration from current date. Cannot be combined with end_date. Format is: `n days`, `n weeks`, `n months`, `n years`, or total intended duration in seconds. (alias: `--duration`) + Updates end_date daily to be duration from the current date, and active SLA rentals are extended with that date. Cannot be combined with end_date. Format is: `n days`, `n weeks`, `n months`, `n years`, or total intended duration in seconds. (alias: `--duration`) From 9c7b2b4529431a93da68a37eddd1707574ebff49 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 19:37:49 -0700 Subject: [PATCH 169/250] docs(sla): address doc-review consensus (cycle 115) State that any sent end date can extend shorter SLA rentals, and document the rent 404 in OpenAPI. Co-authored-by: Cursor --- api-reference/openapi.yaml | 11 ++++++++++- api-reference/openapi/yaml/create_instance.yaml | 2 ++ api-reference/openapi/yaml/schedule_maint.yaml | 4 +++- guides/instances/choosing/sla-coverage.mdx | 8 ++++---- host/hosting-overview.mdx | 6 +++--- host/sla-offers.mdx | 12 ++++++------ snippets/host/cli/list-machine.mdx | 4 +++- snippets/host/sdk/list-machine.mdx | 3 ++- 8 files changed, 33 insertions(+), 17 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index f9c5ab4c..89d0be1e 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1863,6 +1863,10 @@ paths: ask_id: type: integer example: 1234567 + '404': + description: The offer was taken while the request was in progress. `error` + is `no_such_ask` and `msg` contains `error 404/3659`. Re-search and do + not retry the same offer ID. '410': description: Offer no longer available (when cancel_unavail is true and instance cannot start) @@ -6381,7 +6385,12 @@ paths: CLI Usage: `vastai schedule maint --sdate --duration - `' + --maintenance_category ` + + + The CLI sends `"not provided"` when `--maintenance_category` is omitted, and + that value is rejected with HTTP 400 `invalid_args`. On REST, an omitted `maintenance_category` + defaults to `other`.' security: - BearerAuth: [] parameters: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index af78ce2e..59cc5baf 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -247,6 +247,8 @@ paths: ask_id: type: integer example: 1234567 + '404': + description: The offer was taken while the request was in progress. `error` is `no_such_ask` and `msg` contains `error 404/3659`. Re-search and do not retry the same offer ID. '410': description: Offer no longer available (when cancel_unavail is true and instance cannot start) content: diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index 8304407e..ebcdc67b 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -13,7 +13,9 @@ paths: description: | Schedules a maintenance window for a specified machine and notifies clients. - CLI Usage: `vastai schedule maint --sdate --duration ` + CLI Usage: `vastai schedule maint --sdate --duration --maintenance_category ` + + The CLI sends `"not provided"` when `--maintenance_category` is omitted, and that value is rejected with HTTP 400 `invalid_args`. On REST, an omitted `maintenance_category` defaults to `other`. security: - BearerAuth: [] parameters: diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 24e34252..94f59dec 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -39,7 +39,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown, then click **RENT**. 5. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA Fee** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). 6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing**. -7. When you are finished, **Destroy** the instance (not only **Stop**) to end ongoing charges—see [If your instance goes down](#if-your-instance-goes-down). Destroy permanently deletes the instance and its disk, so copy off anything you need first. +7. When you are finished, **Destroy** the instance. On an SLA rental, charges for intended compute, storage, and the SLA fee continue while the instance is unavailable; **Stop** does not end that. Destroy deletes the disk. Whether **Stop** on a healthy instance is billed the same way is not specified. See [What you pay during an outage](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -326,13 +326,13 @@ Billing continues during downtime. You are still charged for **compute, storage, **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and the service credit is the compensation for that downtime. -**Stop vs destroy:** Stopping pauses compute but storage and contract charges can continue. **Destroying the instance** ends future daily charges; final SLA settlement still posts when the contract closes. If you abandon a failed host, destroy only after saving any data you need. +**Stop vs destroy:** While an SLA instance is unavailable, **Stop** does not end intended compute, storage, or SLA fee charges. Only **Destroy** ends future charges, and Destroy deletes the disk. Whether **Stop** on a healthy instance is billed the same way is not specified. Final SLA settlement still posts when the contract closes. If you abandon a failed host, destroy only after saving any data you need. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. ### How reliability is measured -Each day, the platform tracks how long your instance was online. Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: +Each day, the platform tracks how long your instance was online. Whether your own Stop, reboot, or a crash in your container counts as host downtime is not specified. Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: - A single bad hour hurts, but does not always trigger the maximum credit. - A pattern of unreliable uptime produces larger credits over time. @@ -368,7 +368,7 @@ Production settlement uses the multi-window reliability blend described above, n 1. Save work and check **Instances** for host/maintenance status. 2. Remember: compute, storage, and SLA fees continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. -3. **Console:** Open **Instances**, select the instance, then **Destroy** to stop future charges. Stopping alone may not end billing for a broken instance—see [Stop vs destroy](#what-you-pay-during-an-outage). Destroy permanently deletes the instance and its disk, so copy off anything you need first. +3. **Console:** Open **Instances**, select the instance, then **Destroy**. On an unavailable SLA instance, **Stop** does not end the charges in [Stop vs destroy](#what-you-pay-during-an-outage). Destroy deletes the disk, so copy off anything you need first. 4. After settlement, check **Account → Billing** in the console for SLA line items (not `GET /api/v0/charges/`). 5. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 0d1a9730..d0b77d6a 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -162,7 +162,7 @@ By default, volume offers will be listed with GPU offers at the same disk price Space is listed in Gigabytes, and price in \$/Gb/Month. ```text Text -vastai list machine -v -z -g .5 -e "12/23/2027" -r 0 -m 1 +vastai list machine -v -z -g .5 -e -r 0 -m 1 ``` You can also directly create a volume offer by running the `vastai list volume` command. @@ -193,9 +193,9 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. Moving the end date later extends every shorter active rental, including its SLA exposure, to the new date. If that request would also raise an existing contract's SLA fee, the immediate response skips that contract. A background job extends it shortly afterward anyway, under its original SLA terms. Do not move the end date later if you need to avoid that. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. Any end date you send, including the current one, extends every active rental that ends sooner, including SLA rentals, under their original terms. Some of those extensions happen a few minutes later. A GPU, disk, or bandwidth price increase blocks that later extension. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). -If you have raised the pricing, you cannot extend the current rental contracts. +If you have raised the pricing, the current rental contracts are not extended at the new price. ## Testing your own machine diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 6135152d..598fcb55 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -43,9 +43,9 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. -6. Set and **Save** your reliability commitment and confidence in **Set Pricing → SLA**. -7. Read [Scheduled maintenance](#scheduled-maintenance) before your first SLA rental (24-hour notice for planned work). -8. **First publish and verify:** **Save** pricing, then click **LIST** (first publish only). If the machine is already listed, **Save** alone updates the live offer. +6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). +7. Set your reliability commitment and Confidence, confirm the SLA fee preview, then click **Save**. If the machine is already listed from step 2, **Save** publishes SLA immediately. +8. **Verify:** the machine shows **Listed** on **Host → Machines**. If it was never listed, click **LIST** once. - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). 9. **Self-test (after LIST):** With the separate client account from step 2, search by `machine_id`, rent with a **Reliability target**, and verify the SLA (billed like any rental)—see [Testing your own machine](/host/hosting-overview#testing-your-own-machine). @@ -221,7 +221,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. If the same request also raises an existing contract's SLA fee (a lower commitment, wider confidence, or `sla_r_claim` set to `0`), the immediate response skips that contract. A background job extends it shortly afterward anyway, under its original SLA terms. The only reliable way to avoid extending SLA rentals is to not move `end_date` later, or to unlist. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Any `end_date` you send, including the offer's current one, extends every active rental that ends sooner, SLA rentals included, under their original terms. The only reliable way to avoid that is to send no `end_date` later than every active rental's end date, or to unlist. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks that later extension. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -316,7 +316,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ }' ``` -Replace `end_date` with the listing's current Unix timestamp from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`. +Replace `end_date` with the listing's current Unix timestamp from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e` (parsed in the machine's local time, not UTC). Use a Unix timestamp for an exact UTC end. Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). @@ -375,7 +375,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. Re-list only machines whose rentals already end on or after the offer end date, or accept the extension. `show machines` does not list each contract's end date, and `DRY_RUN` does not either, so you cannot check this beforehand. After a live run, read `upd_contracts` in the output. -Run this only when an SLA listing is missing from search after a daemon update even though **Set Pricing** still shows SLA. Healthy listings do not need a re-list, and every re-list can extend shorter active contracts. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. +Run this only when an SLA listing is missing from search after a daemon update even though **Set Pricing** still shows SLA. A fully rented machine is absent from search too. Do not re-list it for that reason. Healthy listings do not need a re-list, and every re-list can extend shorter active contracts. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. `show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 32af5378..b4039924 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -75,7 +75,9 @@ We strongly recommend you test the machine first and only list when ready. Alway ## Examples ```bash -vastai list machine -g 3.50 -e "01/01/2030" +# On a live listing, -e extends active rentals that end sooner (including SLA). +# Reuse the current end date and storage price when you only want to reprice. +vastai list machine -g 3.50 -s -e ``` ## Global Options diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index f4629405..58d83c89 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -67,6 +67,7 @@ from vastai import VastAI client = VastAI(api_key="YOUR_API_KEY") # Base listing only — for SLA, use the console or REST create_asks after list_machine() # see SLA Offers → API (for automation): /host/sla-offers#api-for-automation -result = client.list_machine(id=12345, price_gpu=3.50, end_date="01/01/2030") +# On a live listing, end_date extends active rentals that end sooner (including SLA). +result = client.list_machine(id=12345, price_gpu=3.50, price_disk=0.10, end_date=CURRENT_END_DATE_UNIX) print(result) ``` From 993a2f86b0239fa2f932fec667d6e86abe9ca922 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 19:47:33 -0700 Subject: [PATCH 170/250] docs(sla): address doc-review consensus (cycle 116) Name the earliest rental end date when avoiding extensions, and include the reserved discount on an outage relist. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 6 +++--- host/hosting-overview.mdx | 6 ++---- host/sla-offers.mdx | 10 +++++----- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 430fce7c..c1730fe6 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -137,7 +137,7 @@ Do not use the Charges API alone to reconcile service credits. The `sla` row is **Host — list, backtest, and earnings.** -Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` can change a listing but cannot read current values. Pair it with `machine_read` so a script can read, then send a full body, because omitted fields reset. It does not backtest or read earnings. Add `billing_read` for earnings. For cron, prefer a `billing_read` key for monitoring and a separate `machine_write` + `machine_read` key for listing changes. +Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` can change a listing but cannot read current values, backtest, or read earnings. Pair it with `machine_read` so a script can read the current listing, then send a full body, because omitted fields reset. `machine_read` also covers the backtester. Add `billing_read` for earnings. For cron, prefer a `billing_read` key for monitoring and a separate `machine_write` + `machine_read` key for listing changes. **Workflow summary:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 3b0fa2aa..70ba5a17 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -23,7 +23,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] ## Arguments - Query to search for. default: 'external=false rentable=true verified=true', pass -n to ignore default + Query to search for. default: `external=false rentable=true verified=true rented=false` (`--help` omits `rented`). Pass `-n` to ignore the default. ## Options diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 51821607..77b0a297 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -54,7 +54,7 @@ All stats shown are the portion of the total machine rented. - Disk speed: The speed of the local storage on the machine in MB/s - Total available disk: The maximum amount of disk space available - DLPERF score: A custom deep learning performance score -- Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. On SLA listings, the breakdown also shows an **SLA Fee** line — see [SLA](/guides/instances/choosing/sla-coverage). +- Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. When you set a **Reliability target**, the breakdown on SLA listings also shows an **SLA Fee** line — see [SLA](/guides/instances/choosing/sla-coverage). - Max Duration: The maximum length of a rental contract on this machine - Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host reliability commitment. - Rental Option: RENT button diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 94f59dec..5e9a793e 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -39,7 +39,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown, then click **RENT**. 5. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA Fee** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). 6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing**. -7. When you are finished, **Destroy** the instance. On an SLA rental, charges for intended compute, storage, and the SLA fee continue while the instance is unavailable; **Stop** does not end that. Destroy deletes the disk. Whether **Stop** on a healthy instance is billed the same way is not specified. See [What you pay during an outage](#what-you-pay-during-an-outage). +7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -326,13 +326,13 @@ Billing continues during downtime. You are still charged for **compute, storage, **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and the service credit is the compensation for that downtime. -**Stop vs destroy:** While an SLA instance is unavailable, **Stop** does not end intended compute, storage, or SLA fee charges. Only **Destroy** ends future charges, and Destroy deletes the disk. Whether **Stop** on a healthy instance is billed the same way is not specified. Final SLA settlement still posts when the contract closes. If you abandon a failed host, destroy only after saving any data you need. +**Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. Do not assume **Stop** ends those charges, and do not expect a service credit for downtime you cause yourself (your own Stop or reboot, a crash in your container, or a stop when your balance hits zero) until support confirms it. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. ### How reliability is measured -Each day, the platform tracks how long your instance was online. Whether your own Stop, reboot, or a crash in your container counts as host downtime is not specified. Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: +Each day, the platform tracks how long your instance was online. Contact support before you treat your own Stop, reboot, or container crash as host downtime. See [Stop vs destroy](#what-you-pay-during-an-outage). Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: - A single bad hour hurts, but does not always trigger the maximum credit. - A pattern of unreliable uptime produces larger credits over time. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index d0b77d6a..f9ecc28f 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -193,9 +193,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -To extend the current rental contracts for all clients on a given machine, change the offer end date to a later time with the same or lower pricing. Any end date you send, including the current one, extends every active rental that ends sooner, including SLA rentals, under their original terms. Some of those extensions happen a few minutes later. A GPU, disk, or bandwidth price increase blocks that later extension. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). - -If you have raised the pricing, the current rental contracts are not extended at the new price. +Sending an end date can extend active rentals, including SLA contracts. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts) for the exact rule. ## Testing your own machine @@ -251,7 +249,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **No SLA rentals:** you can set the offer end date to the latest rental end date so new rentals end together, then unlist and maintain. +- **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. - **SLA rentals:** unlist instead. Moving the end date later extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 598fcb55..b2441fd4 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -44,7 +44,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). -7. Set your reliability commitment and Confidence, confirm the SLA fee preview, then click **Save**. If the machine is already listed from step 2, **Save** publishes SLA immediately. +7. Review the SLA fee preview. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. Press **Save** only after you accept the preview. 8. **Verify:** the machine shows **Listed** on **Host → Machines**. If it was never listed, click **LIST** once. - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -221,7 +221,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Any `end_date` you send, including the offer's current one, extends every active rental that ends sooner, SLA rentals included, under their original terms. The only reliable way to avoid that is to send no `end_date` later than every active rental's end date, or to unlist. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks that later extension. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. To avoid extending contracts, send an `end_date` no later than the **earliest** active rental end date, or unlist. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. Raising the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -235,7 +235,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. 4. Set your **reliability commitment** (the console control is **Claim**; the API field is `sla_r_claim`). Renters see it as expected reliability on the offer. Set **Confidence** too. For a new or volatile machine, start with **Wide**. Wider confidence charges a higher SLA fee, which is a cushion against credits; it does not reduce what you owe when a day misses the target. Move to **Normal** (`sla_sigma_x ≈ 0.5`) once uptime is stable. See [Confidence values](#confidence-values). -5. Save and confirm the SLA fee preview before listing. +5. Confirm the SLA fee preview, then click **Save**. On an already-listed machine, **Save** publishes SLA immediately. 6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. #### Updating SLA on an already-listed machine @@ -698,7 +698,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **Severe outage (active SLA contracts):** 1. **Save your current terms before you unlist.** After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, and SLA terms. The snapshot does not include confidence (`sla_sigma_x`; only the `sla_confidence` label) or hidden status (`hidden_listing`). Write both down either way. - **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, and Confidence (Tight, Normal, or Wide). + **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, Confidence (Tight, Normal, or Wide), the reserved discount, and the interruptible min bid. An omitted reserved discount on a new ask becomes `0.4`. ```bash vastai show machines --raw --api-key "$VAST_API_KEY" \ @@ -713,7 +713,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. When you relist, use the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), and Confidence (`sla_sigma_x`). Send `sla_sigma_x` explicitly; a new ask otherwise defaults to 0.5. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. When you relist, use the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. If the snapshot lacks the discount or min bid, use the console notes. Relisting creates a new ask, and an omitted `credit_discount_max` becomes `0.4`. Send `sla_sigma_x` explicitly; a new ask otherwise defaults to 0.5. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing From fe7a891773580bd3e7d923f7e13486ab9f921ac4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 19:58:57 -0700 Subject: [PATCH 171/250] docs(sla): address doc-review consensus (cycle 117) Publish SLA only after a non-SLA listing test, and state that search ignores the rented filter. Co-authored-by: Cursor --- api-reference/openapi.yaml | 10 +++------- api-reference/openapi/yaml/search_offers.yaml | 5 +---- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/hosting-overview.mdx | 6 +++--- host/sla-offers.mdx | 14 +++++++++----- 5 files changed, 18 insertions(+), 21 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 89d0be1e..1afdc4ed 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6647,18 +6647,14 @@ paths: eq: true rented: type: object - description: 'When set to true, include offers where the calling - user already has rented GPUs. - - This is useful for finding offers on machines you''re already - renting. + description: 'Not a server-side filter. The server drops this key. + Each offer still includes a `rented` flag. The CLI applies `rented=false` + on the client after the response. ' properties: eq: type: boolean - default: - eq: false gpu_name: type: object description: 'GPU model name. Example: {"eq": "RTX_4090"} or {"in": diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index 368a2453..56518d03 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -70,13 +70,10 @@ paths: rented: type: object description: | - When set to true, include offers where the calling user already has rented GPUs. - This is useful for finding offers on machines you're already renting. + Not a server-side filter. The server drops this key. Each offer still includes a `rented` flag. The CLI applies `rented=false` on the client after the response. properties: eq: type: boolean - default: - eq: false gpu_name: type: object description: 'GPU model name. Example: {"eq": "RTX_4090"} or {"in": ["RTX_3090", "RTX_4090"]}' diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 5e9a793e..fe2b2676 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -230,7 +230,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -The CLI default query sends `external=false rentable=true verified=true rented=false` (the `--help` text omits `rented`; see [search offers](/cli/reference/search-offers)). The body above matches the first three filters, and REST `POST /api/v0/bundles/` may default omitted `rented` to `{"eq": false}` per [Search Offers OpenAPI](/api-reference/search/search-offers). Pass `rented` explicitly when you need different behavior. +The CLI default query sends `external=false rentable=true verified=true rented=false` (the `--help` text omits `rented`; see [search offers](/cli/reference/search-offers)). REST `POST /api/v0/bundles/` does **not** filter on `rented`. The server drops that key and returns a `rented` flag on each offer. Drop rows where `rented` is true if you need to hide GPUs you already rent. The CLI `rented=false` default does that filtering in the client. **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: @@ -368,7 +368,7 @@ Production settlement uses the multi-window reliability blend described above, n 1. Save work and check **Instances** for host/maintenance status. 2. Remember: compute, storage, and SLA fees continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. -3. **Console:** Open **Instances**, select the instance, then **Destroy**. On an unavailable SLA instance, **Stop** does not end the charges in [Stop vs destroy](#what-you-pay-during-an-outage). Destroy deletes the disk, so copy off anything you need first. +3. **Console:** Open **Instances**, select the instance, then **Destroy** to end charges on an unavailable SLA instance. See [Stop vs destroy](#what-you-pay-during-an-outage). Destroy deletes the disk, so copy off anything you need first. 4. After settlement, check **Account → Billing** in the console for SLA line items (not `GET /api/v0/charges/`). 5. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index f9ecc28f..54ee9e4a 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts will be created at the new terms, while old rental contracts continue at their original terms. This means a single machine may have active rental contracts at different prices and different rental end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. Existing contracts keep their original end dates only when the relist raises the GPU, disk, or bandwidth price. A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. @@ -193,7 +193,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -Sending an end date can extend active rentals, including SLA contracts. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts) for the exact rule. +Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. For SLA rentals, an extension also extends service-credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). ## Testing your own machine @@ -250,7 +250,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. - **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. -- **SLA rentals:** unlist instead. Moving the end date later extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **SLA rentals:** unlist, the same as above. Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index b2441fd4..7c38f54b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -38,17 +38,17 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist -1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**—listing not required yet). +1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. 2. Publish once **without** SLA (leave Claim at `0`) and test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). 7. Review the SLA fee preview. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. Press **Save** only after you accept the preview. -8. **Verify:** the machine shows **Listed** on **Host → Machines**. If it was never listed, click **LIST** once. +8. **Verify the live SLA offer.** The machine has been listed since step 2, so **Save** in step 7 already published the SLA terms. From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). -9. **Self-test (after LIST):** With the separate client account from step 2, search by `machine_id`, rent with a **Reliability target**, and verify the SLA (billed like any rental)—see [Testing your own machine](/host/hosting-overview#testing-your-own-machine). +9. With the client account from step 2, rent your own offer with a **Reliability target** and confirm the SLA Fee line (billed like any rental). See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). ## Before you enable SLA @@ -59,7 +59,7 @@ If you expect downtime during active rentals, notify renters before you take the **Pre-flight checklist (before tuning reliability commitment and confidence):** - Hosting requires a separate host account and hosting agreement — see [Account setup](/host/hosting-overview#account-setup-and-hosting-agreement) if you have not completed host onboarding. -- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai) to request access before configuring a fleet. Approval timing varies; complete host setup and have base pricing ready in **Set Pricing** (a public **LIST** is not required for SLA approval—follow the [SLA host checklist](#sla-host-checklist) and **LIST** in step 8 when SLA economics are finalized). +- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai) to request access before configuring a fleet. Approval timing varies; complete host setup and have base pricing ready in **Set Pricing** (a public **LIST** is not required for SLA approval—follow the [SLA host checklist](#sla-host-checklist): list without SLA in step 2, then **Save** SLA in step 7, which goes live immediately). - Ensure your host daemon is current per the [host setup guide](https://cloud.vast.ai/host/setup/). - If listing fails with `sla_not_approved` or `sla_daemon_outdated`, resolve eligibility before changing SLA parameters. - **Planned maintenance tooling:** Use [`vastai schedule maint`](/host/cli/schedule-maint) or REST — see [Scheduled maintenance](#scheduled-maintenance). @@ -202,7 +202,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.99999**. Exactly `1.0` is rejected. -- If you send `sla_sigma_x`, it must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. If you enable SLA on an existing ask without sending it, the request is accepted and `show machines` can report `sla_confidence: null`. If a value is already stored, omitting it keeps that value. Send it explicitly the first time you enable SLA. +- If you send `sla_sigma_x`, it must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. **Always send `sla_sigma_x` when you enable SLA.** If the claim is above `0` and `show machines` reports `sla_confidence: null`, search quotes a **$0** SLA fee while settlement uses Normal confidence (`0.5`). If a value is already stored, omitting it keeps that value. - Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. @@ -457,6 +457,10 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if ! echo "$machine" | jq -e '(.sla_reliability_claim // 0) > 0' >/dev/null; then echo "skip $id: no SLA terms visible (SLA off, daemon below SLA minimum, or account not SLA-approved)"; continue fi + if ! echo "$machine" | jq -e '.sla_confidence != null' >/dev/null; then + echo "skip $id: SLA enabled but no stored confidence; set sla_sigma_x first" >&2 + continue + fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. # price_disk is required: null or omitted resets storage price to 0.10. # Rolling (-l) listings are included. Resend duration as an integer (whole seconds) so auto-renew stays on. From 73e0e39cbf7f4707f8cd843b59066918124fb7cc Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 20:11:38 -0700 Subject: [PATCH 172/250] docs(sla): address doc-review consensus (cycle 118) State Stop billing as unconfirmed, and align extension, search, and CLI reprice notes. Co-authored-by: Cursor --- api-reference/openapi.yaml | 2 -- api-reference/openapi/yaml/search_offers.yaml | 2 -- cli/reference/search-offers.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 6 ++++-- guides/reference/billing.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 6 +++--- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 2 +- 9 files changed, 13 insertions(+), 15 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 1afdc4ed..dbf20162 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6900,8 +6900,6 @@ paths: eq: true rentable: eq: true - rented: - eq: false responses: '200': description: Successful search response diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index 56518d03..b7d2b789 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -286,8 +286,6 @@ paths: eq: true rentable: eq: true - rented: - eq: false responses: '200': description: Successful search response diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 70ba5a17..74df3459 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -196,9 +196,9 @@ bool = True | False | `expected_reliability` | Host reliability commitment (also a query key; see Available Fields) | -SLA query keys (`has_sla`, `expected_reliability`, `target_reliability`) are accepted by search. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. +REST search accepts the SLA query keys `has_sla`, `expected_reliability`, and `target_reliability`. The CLI can send only `has_sla` and `expected_reliability`. A CLI `target_reliability` filter is sent as an operator object and returns HTTP 400. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. -The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": 0.95` (a plain number; `{"eq": 0.95}` is rejected with 400). In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla`, `target_reliability`, and `expected_reliability`. The warning is harmless: the fields are still sent. To self-check, run `--raw | jq 'all(.[]; .expected_reliability > 0)'` (CLI `--raw` prints a bare array of offers, not an `offers` object). +The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": 0.95` (a plain number; `{"eq": 0.95}` is rejected with 400). In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla` and `expected_reliability`. The warning is harmless: those fields are still sent. `target_reliability` is not in that harmless set. To self-check, run `--raw | jq 'all(.[]; .expected_reliability > 0)'` (CLI `--raw` prints a bare array of offers, not an `offers` object). ## Global Options diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index fe2b2676..6f42725e 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -326,18 +326,20 @@ Billing continues during downtime. You are still charged for **compute, storage, **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and the service credit is the compensation for that downtime. -**Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. Do not assume **Stop** ends those charges, and do not expect a service credit for downtime you cause yourself (your own Stop or reboot, a crash in your container, or a stop when your balance hits zero) until support confirms it. Final SLA settlement still posts when the contract closes. +**Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. Whether **Stop** on a healthy SLA instance ends the GPU charge and the SLA fee is **not confirmed**. Until it is, treat **Stop** as not ending those charges, and **Destroy** when you are done. Whether downtime you cause yourself (your own Stop or reboot, a crash in your container, or a stop when your balance hits zero) earns a service credit is also **not confirmed**. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. ### How reliability is measured -Each day, the platform tracks how long your instance was online. Contact support before you treat your own Stop, reboot, or container crash as host downtime. See [Stop vs destroy](#what-you-pay-during-an-outage). Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: +Each day, the platform tracks how long your instance was online. Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: - A single bad hour hurts, but does not always trigger the maximum credit. - A pattern of unreliable uptime produces larger credits over time. - One strong day after a weak week does not instantly reset everything. +Contact support before you treat your own Stop, reboot, or container crash as host downtime. See [Stop vs destroy](#what-you-pay-during-an-outage). + When a host schedules maintenance in advance, part of that downtime is counted as uptime for the host. More of the window is forgiven the earlier they give notice, and less is forgiven the longer the window lasts. Forgiven downtime does not earn you a service credit. Check **Instances** status and any notifications to distinguish planned maintenance from an unexpected outage. Unplanned outages count fully. ### Credit scenarios (simplified) diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index 9fa29dc3..e2e01f2b 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -19,7 +19,7 @@ We accept credit card payments through Stripe and crypto payments through BitPay Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. **When your balance reaches zero (or below):** - - Your instances are **stopped automatically**. + - Your instances are **stopped automatically**. Whether that stop ends GPU and SLA-fee charges on an SLA rental is not confirmed. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. - To protect accounts with established usage history, **the system allows a short grace period where your balance may go negative before deletion occurs** -- the length of this buffer is calculated based on your account's average daily spend. Accounts with higher historical spend receive a proportionally larger buffer. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 54ee9e4a..5240ba93 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -42,7 +42,7 @@ Clients have high expectations coming from AWS or GCP. As a host, plan to offer ## Offers and Rental Contracts -Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or `PUT /api/v0/machines/create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). +Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or `PUT /api/v0/machines/create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). Repricing an already-listed SLA machine with the CLI keeps the current SLA terms. A relist after unlist creates a new ask without SLA. The main offer parameters include: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 7c38f54b..72d893d7 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -221,7 +221,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. To avoid extending contracts, send an `end_date` no later than the **earliest** active rental end date, or unlist. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. Raising the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist, or accept the extension and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. Raising the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -292,7 +292,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_END_DATE_UNIX` with the machine's current `end_date` from `show machines`, as a number with no quotes. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (it defaults to 1 only when offers are created or re-created). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. -Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request would raise its price or SLA fee. Resending the offer's current `end_date` is not a no-op when some rentals end sooner. Check `results[0].upd_contracts` to see which contracts were extended. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). +Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price. A change that only raises the SLA fee does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). #### Full listing update (existing ask) @@ -372,7 +372,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge -Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. Re-list only machines whose rentals already end on or after the offer end date, or accept the extension. `show machines` does not list each contract's end date, and `DRY_RUN` does not either, so you cannot check this beforehand. After a live run, read `upd_contracts` in the output. +Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. You cannot see per-contract end dates beforehand. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). Run this only when an SLA listing is missing from search after a daemon update even though **Set Pricing** still shows SLA. A fully rented machine is absent from search too. Do not re-list it for that reason. Healthy listings do not need a re-list, and every re-list can extend shorter active contracts. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index b4039924..87d7f6dc 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). Volume/duration options (`-v`, `-z`, `-l`) work today. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. Volume/duration options (`-v`, `-z`, `-l`) work today. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. ## Usage diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 58d83c89..3067c53d 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). `list_machine()` cannot send `hidden_listing`. A later reprice through the SDK or CLI makes a hidden listing public and can reset storage price and auto-renew. Update hidden SLA listings with REST and send `hidden_listing` explicitly. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so Claim and Confidence stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`. A later reprice through the SDK or CLI makes a hidden listing public and can reset storage price and auto-renew. Update hidden SLA listings with REST and send `hidden_listing` explicitly. ## Signature From 9a2b1bbb7dcf8832cd2190f53ea5b311a7cb41e7 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 20:23:28 -0700 Subject: [PATCH 173/250] docs(sla): address doc-review consensus (cycle 119) Correct the credit-table comparison, 429 handling, console publish order, and CLI reprice side effects. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 8 ++++---- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 20 ++++++++++++++------ snippets/host/cli/list-machine.mdx | 7 ++++--- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 6f42725e..29db2e3c 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -295,7 +295,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | -| Too many requests | HTTP 429. Stay at or below about 10 search requests per minute per IP (Search Offers `x-rate-limit`). Back off on HTTP 429 before sending more. Space rent calls about 5 seconds apart (the rent endpoint's rate-limit threshold is 4.5). The body is `{"detail": ...}`, not `{success, error, msg}`. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Too many requests | HTTP 429. Detect throttling by the status code. The body differs by endpoint (JSON `msg`/`error` or plain text), so do not parse a `detail` field. Stay at or below about 10 search requests per minute per IP. If a `Retry-After` header is present, honor it. Space rent calls at least 5 seconds apart (threshold 4.5). OpenAPI `penalty: 12` on rent is seconds added to the server's last-request time, so a burst can block longer than that spacing. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message includes `error 403/3586` ("Hosts can only rent their own machines"). The HTTP status is 400, not 403. A host-only key gets this for every offer that is not on its own machines, including a missing offer. | Switch to a renter account key, then re-search (see [Hosting Overview](/host/hosting-overview) self-test note). | @@ -346,13 +346,13 @@ When a host schedules maintenance in advance, part of that downtime is counted a Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host reliability commitment 99%). A day's service credit is capped relative to that UTC day's covered compute (GPU, storage, and bandwidth combined). The dollar figures below use GPU cost only. -| Scenario | Approx. SLA fee | Approx. service credit | Net vs no SLA (approx.) | +| Scenario | Approx. SLA fee | Approx. service credit | Credit minus SLA fee | | --- | --- | --- | --- | | Above target (excellent / good day) | ~$0.20/day | $0 | **−$0.20** (you paid the SLA fee) | -| Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (net credit after SLA fee) | +| Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (credit after the SLA fee) | | Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | -**How to read “Net vs no SLA”:** negative = you paid more than without SLA; positive = you received a net credit versus renting the same offer without the SLA. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day where the **blended measure** meets your target does not pay a credit. Raw daily uptime can sit at or slightly above the target while the blended measure is still below it. +**How to read “Credit minus SLA fee”:** this column is only the service credit minus the SLA fee. It is not your net versus a non-SLA rental. On an SLA rental, offline time is still billed as intended compute. On a non-SLA rental it is not, so add that billed downtime when you compare the two. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day where the **blended measure** meets your target does not pay a credit. Raw daily uptime can sit at or slightly above the target while the blended measure is still below it. Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 5240ba93..fb4c654d 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -42,7 +42,7 @@ Clients have high expectations coming from AWS or GCP. As a host, plan to offer ## Offers and Rental Contracts -Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or `PUT /api/v0/machines/create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). Repricing an already-listed SLA machine with the CLI keeps the current SLA terms. A relist after unlist creates a new ask without SLA. +Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or `PUT /api/v0/machines/create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). Repricing an already-listed SLA machine with the CLI keeps the current SLA terms, but omitting `-l` clears auto-renew and omitting `-v` can create a volume offer. A relist after unlist creates a new ask without SLA. The main offer parameters include: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 72d893d7..9108ec90 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -31,7 +31,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong | Goal | Start here | | --- | --- | | Understand what SLA is | [SLA in plain language](#sla-in-plain-language) | -| Preview economics and enable SLA in the console | [How it works](#how-it-works-plain-english) → [Listing an SLA offer](#listing-an-sla-offer). For downtime, use the console ([Set a maintenance window](/host/set-maintenance-window)) or [CLI/REST](#scheduled-maintenance). Use one path per window. | +| Preview economics and enable SLA in the console | [SLA host checklist](#sla-host-checklist) (list and test without SLA first). For downtime, use the console ([Set a maintenance window](/host/set-maintenance-window)) or [CLI/REST](#scheduled-maintenance). Use one path per window. | | Enable or update SLA via API | [Before you enable SLA](#before-you-enable-sla) → [API (for automation)](#api-for-automation) | | I list with CLI only (no SLA flags yet) | **Set Pricing → SLA** + **LIST** in the console, or REST `PUT /api/v0/machines/create_asks/` — SLA flags are **not** in `vastai list machine` yet | | Monitor settlement after listing | [Monitoring SLA after listing](#monitoring-sla-after-listing) | @@ -44,7 +44,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). -7. Review the SLA fee preview. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. Press **Save** only after you accept the preview. +7. Review the SLA fee preview. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. Press **Save** only after you accept the preview. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) first. 8. **Verify the live SLA offer.** The machine has been listed since step 2, so **Save** in step 7 already published the SLA terms. From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -202,7 +202,13 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.99999**. Exactly `1.0` is rejected. -- If you send `sla_sigma_x`, it must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. **Always send `sla_sigma_x` when you enable SLA.** If the claim is above `0` and `show machines` reports `sla_confidence: null`, search quotes a **$0** SLA fee while settlement uses Normal confidence (`0.5`). If a value is already stored, omitting it keeps that value. +- If you send `sla_sigma_x`, it must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. **Always send `sla_sigma_x` when you enable SLA.** If the claim is above `0` and confidence was never stored, search can quote a **$0** SLA fee while you still carry credit exposure. If a value is already stored, omitting it keeps that value. + +```bash +vastai show machines --raw | jq -r '.machines[] | select((.sla_reliability_claim // 0) > 0 and .sla_confidence == null) | .id' +``` + +For each ID that prints, PUT `sla_sigma_x` (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). - Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. @@ -231,12 +237,14 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover ### Web console +**New machine?** Complete [SLA host checklist](#sla-host-checklist) steps 1–2 first (list and test **without** SLA). Then set SLA here. + 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. 3. Expand **SLA**. 4. Set your **reliability commitment** (the console control is **Claim**; the API field is `sla_r_claim`). Renters see it as expected reliability on the offer. Set **Confidence** too. For a new or volatile machine, start with **Wide**. Wider confidence charges a higher SLA fee, which is a cushion against credits; it does not reduce what you owe when a day misses the target. Move to **Normal** (`sla_sigma_x ≈ 0.5`) once uptime is stable. See [Confidence values](#confidence-values). 5. Confirm the SLA fee preview, then click **Save**. On an already-listed machine, **Save** publishes SLA immediately. -6. After saving pricing, click **LIST** on the Host Machines page (or confirm the machine status changes to **listed**). Saving pricing alone stores your offer settings; listing publishes the offer to search. +6. **First publish only:** after saving pricing, click **LIST**. On a machine that is already listed, **Save** in step 5 already published SLA. Skip this step. #### Updating SLA on an already-listed machine @@ -250,7 +258,7 @@ If the machine is already **listed**: - **Search:** `dph_total` includes the SLA fee at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). -In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes the offer to search. `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same publish step as **LIST**; SLA parameters require this REST body or **Set Pricing → SLA**, not `vastai list machine` flags). +In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIST** publishes a new listing (on a machine that is already listed, **Save** is already live). `PUT /api/v0/machines/create_asks/` performs both steps in one request — it creates or updates the **live listing** (same publish step as **LIST**; SLA parameters require this REST body or **Set Pricing → SLA**, not `vastai list machine` flags). #### Web console SLA preview @@ -375,7 +383,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. You cannot see per-contract end dates beforehand. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). -Run this only when an SLA listing is missing from search after a daemon update even though **Set Pricing** still shows SLA. A fully rented machine is absent from search too. Do not re-list it for that reason. Healthy listings do not need a re-list, and every re-list can extend shorter active contracts. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. +Run this only when an SLA listing is missing from search after a daemon update even though **Set Pricing** still shows SLA. A fully rented machine is absent from search too. Do not re-list it for that reason. Healthy listings do not need a re-list, and every re-list can extend shorter active contracts. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. `show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 87d7f6dc..e1999bae 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. Volume/duration options (`-v`, `-z`, `-l`) work today. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. The CLI still sends the other listing fields you leave out. Omitting `-l` clears auto-renew (`duration`); pass `-l` again to keep it. Omitting `-v` can create a volume offer at half the free disk; pass `-v 0` to skip that. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. ## Usage @@ -53,7 +53,7 @@ vastai list machine ID [options] - Updates end_date daily to be duration from the current date, and active SLA rentals are extended with that date. Cannot be combined with end_date. Format is: `n days`, `n weeks`, `n months`, `n years`, or total intended duration in seconds. (alias: `--duration`) + Moves `end_date` forward daily so it stays this long from the current date. Active rentals that end sooner, including SLA rentals, are extended to that date. Cannot be combined with `--end_date`. Format is: `n days`, `n weeks`, `n months`, `n years`, or total intended duration in seconds. (alias: `--duration`) @@ -77,7 +77,8 @@ We strongly recommend you test the machine first and only list when ready. Alway ```bash # On a live listing, -e extends active rentals that end sooner (including SLA). # Reuse the current end date and storage price when you only want to reprice. -vastai list machine -g 3.50 -s -e +vastai list machine -g 3.50 -s -v 0 -e +# For an auto-renew listing, pass -l again instead of -e. ``` ## Global Options From 7f8b6f93a01d4a8cb40e532e627f9e5df968f8e0 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 20:33:03 -0700 Subject: [PATCH 174/250] docs(sla): address doc-review consensus (cycle 120) Fix the jq end_date guard and replace draft billing wording with instructions hosts and renters can follow. Co-authored-by: Cursor --- cli/reference/create-instance.mdx | 3 ++- guides/instances/choosing/sla-coverage.mdx | 4 ++-- guides/reference/billing.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 10 +++++----- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 2 +- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 15d2e7af..fce9fbf1 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -154,7 +154,8 @@ vastai create instance 1000001 --template_hash TEMPLATE_HASH --disk 64 # create an on-demand instance with the pytorch/pytorch image, 40GB of disk, open 8081 udp, direct ssh, set hostname to billybob, and a small onstart script vastai create instance 1000002 --image pytorch/pytorch --disk 40 --env '-p 8081:8081/udp -h billybob' --ssh --direct --onstart-cmd "env | grep _ >> /etc/environment; echo 'starting up'"; -# create an on-demand instance with a private image (use your registry password, not a real secret in docs) +# create an on-demand instance with a private image +# replace YOUR_USER / YOUR_PASSWORD with your registry credentials vastai create instance 1000003 --image YOUR_REGISTRY/pytorch:latest --login '-u YOUR_USER -p YOUR_PASSWORD docker.io' --jupyter --direct --env '-e TZ=PDT -e XNAME=XX4 -p 22:22 -p 8080:8080' --disk 20 # create an on-demand instance with the pytorch/pytorch image, 40GB of disk, override the entrypoint to bash and pass bash a simple command to keep the instance running. (args launch without ssh/jupyter) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 29db2e3c..852025a6 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -314,7 +314,7 @@ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** be When you rent an SLA-backed offer **with a target set**: 1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA fee line or `dph_total`. Host confidence is not shown in the web console and is not a setting you control. -2. **Daily billing** — you pay compute plus the SLA fee each day. +2. **Charges and settlement** — compute and the SLA fee accrue while the contract is active, the same way compute does on any rental (see [Billing](/guides/reference/billing)). Only SLA settlement (service credits) happens once per UTC day. 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA fee with no credit. @@ -326,7 +326,7 @@ Billing continues during downtime. You are still charged for **compute, storage, **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and the service credit is the compensation for that downtime. -**Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. Whether **Stop** on a healthy SLA instance ends the GPU charge and the SLA fee is **not confirmed**. Until it is, treat **Stop** as not ending those charges, and **Destroy** when you are done. Whether downtime you cause yourself (your own Stop or reboot, a crash in your container, or a stop when your balance hits zero) earns a service credit is also **not confirmed**. Final SLA settlement still posts when the contract closes. +**Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. **Destroy** the instance when you are done. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index e2e01f2b..ed0b7916 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -19,7 +19,7 @@ We accept credit card payments through Stripe and crypto payments through BitPay Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. **When your balance reaches zero (or below):** - - Your instances are **stopped automatically**. Whether that stop ends GPU and SLA-fee charges on an SLA rental is not confirmed. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). + - Your instances are **stopped automatically**. If you rent with an SLA, a stop at zero balance is not guaranteed to end the GPU charge or the SLA fee. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. - To protect accounts with established usage history, **the system allows a short grace period where your balance may go negative before deletion occurs** -- the length of this buffer is calculated based on your account's average daily spend. Accounts with higher historical spend receive a proportionally larger buffer. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index fb4c654d..d840026a 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -42,7 +42,7 @@ Clients have high expectations coming from AWS or GCP. As a host, plan to offer ## Offers and Rental Contracts -Hosts can create offers (sometimes called listings) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or `PUT /api/v0/machines/create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). Repricing an already-listed SLA machine with the CLI keeps the current SLA terms, but omitting `-l` clears auto-renew and omitting `-v` can create a volume offer. A relist after unlist creates a new ask without SLA. +Hosts can create offers (sometimes called listings; the API calls an offer an **ask**) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or `PUT /api/v0/machines/create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). Repricing an already-listed SLA machine with the CLI keeps the current SLA terms, but omitting `-l` clears auto-renew and omitting `-v` can create a volume offer. A relist after unlist creates a new ask without SLA. The main offer parameters include: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 9108ec90..c8d8879e 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -59,7 +59,7 @@ If you expect downtime during active rentals, notify renters before you take the **Pre-flight checklist (before tuning reliability commitment and confidence):** - Hosting requires a separate host account and hosting agreement — see [Account setup](/host/hosting-overview#account-setup-and-hosting-agreement) if you have not completed host onboarding. -- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai) to request access before configuring a fleet. Approval timing varies; complete host setup and have base pricing ready in **Set Pricing** (a public **LIST** is not required for SLA approval—follow the [SLA host checklist](#sla-host-checklist): list without SLA in step 2, then **Save** SLA in step 7, which goes live immediately). +- Confirm SLA is enabled for your account. In the console, open **Set Pricing → SLA** on a machine — if the panel is missing or listing returns `sla_not_approved`, contact [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai) to request access before configuring a fleet. Approval timing varies; complete host setup and have base pricing ready in **Set Pricing**. A public **LIST** is not required to request SLA approval. To turn SLA on, follow the [SLA host checklist](#sla-host-checklist): list without SLA (step 2), test, then **Save** SLA (step 7). On a listed machine, **Save** goes live immediately. - Ensure your host daemon is current per the [host setup guide](https://cloud.vast.ai/host/setup/). - If listing fails with `sla_not_approved` or `sla_daemon_outdated`, resolve eligibility before changing SLA parameters. - **Planned maintenance tooling:** Use [`vastai schedule maint`](/host/cli/schedule-maint) or REST — see [Scheduled maintenance](#scheduled-maintenance). @@ -145,7 +145,7 @@ For SLA-covered on-demand contracts, compute billing uses the **intended daily c ## SLA parameters -When you list or update a machine, set SLA fields via the host console or `PUT /api/v0/machines/create_asks/` (see [Listing an SLA offer](#listing-an-sla-offer) below). +When you list or update a machine, set SLA fields via the host console or `PUT /api/v0/machines/create_asks/` (see [Listing an SLA offer](#listing-an-sla-offer) below). In the API, an offer (listing) is called an **ask**. A new ask means the offer was recreated, and settings you do not send again are reset. | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | @@ -203,13 +203,13 @@ Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.99999**. Exactly `1.0` is rejected. - If you send `sla_sigma_x`, it must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. **Always send `sla_sigma_x` when you enable SLA.** If the claim is above `0` and confidence was never stored, search can quote a **$0** SLA fee while you still carry credit exposure. If a value is already stored, omitting it keeps that value. +- Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. ```bash vastai show machines --raw | jq -r '.machines[] | select((.sla_reliability_claim // 0) > 0 and .sla_confidence == null) | .id' ``` For each ID that prints, PUT `sla_sigma_x` (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). -- Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. If listing is rejected with `error: "invalid_sla_params"`, check the `msg` field against the rules above. Other SLA listing errors include `sla_not_approved` and `sla_daemon_outdated`. @@ -227,7 +227,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist, or accept the extension and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. Raising the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. Raising the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -455,7 +455,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: missing end_date and duration"; continue fi now=$(date -u +%s) - if ! jq -e -n --argjson end "$end" --argjson now "$now" '$end > $now' >/dev/null 2>&1; then + if ! jq -e -n --argjson e "$end" --argjson n "$now" '$e > $n' >/dev/null 2>&1; then echo "skip machine_id=$id: end_date expired"; continue fi fi diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index e1999bae..c29c031a 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. The CLI still sends the other listing fields you leave out. Omitting `-l` clears auto-renew (`duration`); pass `-l` again to keep it. Omitting `-v` can create a volume offer at half the free disk; pass `-v 0` to skip that. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. For any other listing field you leave out, the CLI sends its default, which overwrites the current setting. Omitting `-l` clears auto-renew (`duration`); pass `-l` again to keep it. Omitting `-v` can create a volume offer at half the free disk; pass `-v 0` to skip that. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. ## Usage diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index f1f7b582..0a77ad6a 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -64,7 +64,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). To reschedule, cancel first, then schedule a new window (≥24 hours ahead for planned maintenance-forgiveness review). Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine. To reschedule, cancel first, then recreate each window you still want (≥24 hours ahead for planned maintenance-forgiveness review). Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. ## Examples From 7ac13de551b6a702c120a08bd431360e73dfb9c5 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 20:41:08 -0700 Subject: [PATCH 175/250] docs(sla): address doc-review consensus (cycle 121) Require min_chunk on CLI reprice, document confidence bands, and keep console renters on the outage section. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 6 +++--- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 2 +- snippets/host/cli/list-machine.mdx | 4 ++-- snippets/host/sdk/list-machine.mdx | 3 ++- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 852025a6..d50c03f6 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -56,7 +56,7 @@ Full steps: [In the web console](#in-the-web-console). CLI/API limits for automa | Automate search → rent → verify | [API automation](#api-automation) | | View service credits | **Account → Billing** (console only today) | -**Console renters (web only).** You do not need an API key. Follow [In the web console](#in-the-web-console), then stop unless you automate. +**Console renters (web only).** You do not need an API key. Follow [In the web console](#in-the-web-console), skip [API automation](#api-automation), and continue at [What happens after you rent](#what-happens-after-you-rent) for outage billing and credits. @@ -127,7 +127,7 @@ Search **quotes** SLA pricing. The SLA starts only when you set **Reliability ta 6. Rent as usual. Your target is locked at rent time. -**Console-only:** You can stop here. SLA rental in the web console does not require CLI or API keys. Continue below only if you automate search or rent. +**Console-only:** Skip [API automation](#api-automation) and continue at [What happens after you rent](#what-happens-after-you-rent). That section covers outage billing, Stop vs Destroy, and when credits appear. SLA rental in the web console does not require CLI or API keys. ### Search filters (console and programmatic search) @@ -181,7 +181,7 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d ### API automation -**Console renters can stop after [In the web console](#in-the-web-console).** This section is for API keys. +**Console renters:** skip this section and continue at [What happens after you rent](#what-happens-after-you-rent). This section is for API keys. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 24149ef4..695bb88a 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -286,7 +286,7 @@ Optional, for API automation only. To check one machine, use the single-machine - The loop reads each machine's `sla_reliability_claim` and `sla_confidence` label from `show machines`. - For machines whose terms are not visible, set `R` (commitment) and `P` (confidence `p`) as fallbacks. That covers machines without SLA yet, and machines whose terms are hidden because they are unlisted, have an outdated daemon, or lack SLA approval. The loop logs every fallback it uses, so check those rows before trusting them. - Machines missing either value, with no `R`/`P` fallback, are skipped and logged. - - The confidence label is a band, so a custom `sla_sigma_x` is backtested at the nearest band's `p`. To test an exact value, use the single-machine request with `p = 1/(1 + sla_sigma_x)`. + - The confidence label is a band. The loop uses one `p` per band: `high` → 0.83 (σ 0.2), `medium` → 0.6667 (σ 0.5), `low` → 0.50 (σ 1.0). `low` covers every σ above 0.71, so a machine listed at σ 2.0 is backtested at `p` 0.50, not at its real `p`. For an exact value, use the single-machine request with `p = 1/(1 + sla_sigma_x)`. 2. Responses are written to a private temp directory that is deleted when the loop exits. ```bash diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index c8d8879e..42370f10 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -369,7 +369,7 @@ vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12 REST equivalent: `GET /api/v0/machines/` (the CLI sends `?owner=me`). The account is the API key owner; a `?user_id=` query is ignored. -Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence` (`high` = Tight, `medium` = Normal, `low` = Wide), not as `sla_sigma_x`. `null` means SLA was never stored on this ask, or the terms are hidden (unlisted machine, outdated daemon, or account not approved for SLA). `0` appears only when SLA was explicitly turned off and the terms are visible. Pricing fields and `end_date` are `null` when the machine is not listed. +Machine `id` may be a string in raw JSON. The response is wrapped in a `machines` array. Read-side names differ from the `create_asks` body: `listed_gpu_cost` → `price_gpu`, `listed_min_gpu_count` → `min_chunk`, `sla_reliability_claim` → `sla_r_claim`. Confidence is returned as a label, `sla_confidence`, not as `sla_sigma_x`: `high` is Tight (σ ≤ 0.32), `medium` is Normal (σ ≤ 0.71), and `low` is Wide (σ above 0.71). Two machines in the same band can have different `sla_sigma_x` and different SLA fees. `null` means SLA was never stored on this ask, or the terms are hidden (unlisted machine, outdated daemon, or account not approved for SLA). `0` appears only when SLA was explicitly turned off and the terms are visible. Pricing fields and `end_date` are `null` when the machine is not listed. Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge → PUT). `vastai list machine` and the Python SDK listing helpers cannot set SLA fields; start from this REST pattern (or the console) when you move an existing CLI listing to SLA. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index c29c031a..f3c36374 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. For any other listing field you leave out, the CLI sends its default, which overwrites the current setting. Omitting `-l` clears auto-renew (`duration`); pass `-l` again to keep it. Omitting `-v` can create a volume offer at half the free disk; pass `-v 0` to skip that. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. For any other listing field you leave out, the CLI sends `null`, which overwrites the current setting. Always pass `-m` with the current `listed_min_gpu_count` (a null `min_chunk` is HTTP 400 `invalid_args`). Omitting `-l` clears auto-renew (`duration`); pass `-l` again to keep it. Omitting `-v` can create a volume offer at half the free disk; pass `-v 0` to skip that. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. ## Usage @@ -77,7 +77,7 @@ We strongly recommend you test the machine first and only list when ready. Alway ```bash # On a live listing, -e extends active rentals that end sooner (including SLA). # Reuse the current end date and storage price when you only want to reprice. -vastai list machine -g 3.50 -s -v 0 -e +vastai list machine -g 3.50 -s -m -v 0 -e # For an auto-renew listing, pass -l again instead of -e. ``` diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 3067c53d..4664c53f 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -68,6 +68,7 @@ client = VastAI(api_key="YOUR_API_KEY") # Base listing only — for SLA, use the console or REST create_asks after list_machine() # see SLA Offers → API (for automation): /host/sla-offers#api-for-automation # On a live listing, end_date extends active rentals that end sooner (including SLA). -result = client.list_machine(id=12345, price_gpu=3.50, price_disk=0.10, end_date=CURRENT_END_DATE_UNIX) +# Replace the numbers with this machine's listed_storage_cost, listed_min_gpu_count, and end_date. +result = client.list_machine(id=12345, price_gpu=3.50, price_disk=0.10, min_chunk=1, end_date=1790000000) print(result) ``` From edae9df2deb596605a27310ffb65843f44af3998 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 20:50:49 -0700 Subject: [PATCH 176/250] docs(sla): address doc-review consensus (cycle 122) Stop SDK reprices from creating volume offers, and state that a short outage above target earns no credit. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 6 ++- guides/reference/billing.mdx | 2 +- guides/reference/faq/billing.mdx | 2 +- sdk/python/reference/create-instance.mdx | 44 +++++++++++++--------- snippets/host/cli/list-machine.mdx | 16 +++++++- snippets/host/sdk/list-machine.mdx | 13 ++++--- 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d50c03f6..87cdf350 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay a small hourly **SLA fee** on top of compute only after you set a **reliability target** at rent time. The console shows that fee as the **SLA Fee** line. API fields call it a premium (for example `slaPremiumPerHour`). If measured uptime falls short of your target, you receive a **service credit**, shown as **Service Credit** in Account → Billing. Search can show the price; it does not turn the SLA on by itself. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay an hourly **SLA fee** on top of compute, but only after you set a **reliability target** at rent time. The fee is usually small when your target is well below the host's reliability commitment. It can approach the GPU price when your target is close to that commitment. The console shows the fee as the **SLA Fee** line. API fields call it a premium (for example `slaPremiumPerHour`). A **service credit** is paid only when measured reliability falls below your target, and it is shown as **Service Credit** in Account → Billing. A short outage that stays above the target is billed with no credit. Search can show the price; it does not turn the SLA on by itself. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -22,7 +22,7 @@ An SLA is an optional reliability promise on an **on-demand** GPU rental. You do A few things people mix up: - The **reliability score** on an offer card is a separate marketplace signal. It is not your SLA. -- The GPU bill does **not** stop during an outage. SLA pays you back later as a credit, usually after the next UTC midnight. +- The GPU bill does **not** stop during an outage. A credit is paid only when the blended measure falls below your target, usually after the next UTC midnight. A short outage that stays above the target is billed in full with no credit. - Filtering for SLA offers (`has_sla`, SLA-enabled), or a CLI or API search, does **not** turn on an SLA. Setting **Reliability target** in the console Search filters and then clicking **RENT**, or sending `target_reliability` on REST rent, does. The CLI cannot turn SLA on. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. - If the price breakdown has **no SLA Fee line**, you do not have an SLA. In **Account → Billing** the same charge appears as **SLA Fee**, and credits as **Service Credit**. In API responses the hourly amount is `slaPremiumPerHour`. @@ -282,6 +282,8 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). If you omit `limit`, the server returns at most **25** rows. A non-positive `limit` is treated as 5, then capped at 25. - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. +**4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. + **Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing** for the itemized **Service Credit**. `GET /api/v0/charges/` requires `select_filters` with `day.gte` and `day.lte` (unix seconds). `results[].items[]` with `type: "sla"` is the SLA fee minus any service credit (the description still says **SLA Fee**). It can be smaller or negative, and it is omitted until the last day in the window has settled. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. **Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour`. Show-instances uses OpenAPI threshold `1.0` (about one request per second). diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index ed0b7916..96d2ce98 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -82,7 +82,7 @@ You are charged the base active rental cost for every second your instance is in You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals are billed for intended compute during downtime and compensated with service credits. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals are billed for intended compute during downtime. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). To see a pricing breakdown on your current instances within your Instance page in the console or from offers on the Search page you can hover over the price to see pricing details. diff --git a/guides/reference/faq/billing.mdx b/guides/reference/faq/billing.mdx index 64656c1b..049b5a3d 100644 --- a/guides/reference/faq/billing.mdx +++ b/guides/reference/faq/billing.mdx @@ -33,7 +33,7 @@ You are charged the storage cost (which depends on the size of your storage allo Stopping an instance does not avoid storage costs. You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals are billed for intended compute during downtime and compensated with service credits. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals are billed for intended compute during downtime. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). ### What is the billing frequency? diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 301b2088..aae88393 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -184,27 +184,37 @@ print(result) **SLA via REST:** `create_instance()` cannot set `target_reliability`. If you only use Python, rent with REST and pass the same target you searched with: ```python +import json import requests offer_id = 12345 # path id: offer/ask ID from search, not a running instance ID -response = requests.put( - f"https://console.vast.ai/api/v0/asks/{offer_id}/", - headers={"Authorization": "Bearer YOUR_API_KEY"}, - json={ - "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", - "disk": 50, - "target_reliability": 0.95, - "label": "rent-YOUR-UUID", - }, - timeout=60, -) -if not response.ok: - print(response.status_code, response.text) # body contains error / msg +label = "rent-YOUR-UUID" +headers = {"Authorization": "Bearer YOUR_API_KEY"} +body = { + "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", + "disk": 50, + "target_reliability": 0.95, + "label": label, +} +try: + response = requests.put( + f"https://console.vast.ai/api/v0/asks/{offer_id}/", + headers=headers, + json=body, + timeout=60, + ) response.raise_for_status() -print(response.json()) # new_contract is the rental instance ID -# On a timeout, dropped connection, 429, or 5xx the rental may already exist. -# Look up label=rent-YOUR-UUID on GET /api/v1/instances/ before sending the same PUT again. -# URL-encode select_filters (curl -G --data-urlencode). +except requests.RequestException: + found = requests.get( + "https://console.vast.ai/api/v1/instances/", + params={"select_filters": json.dumps({"label": {"eq": label}})}, + headers=headers, + timeout=30, + ) + found.raise_for_status() + # If this returns no instance, re-search and PUT again with a new offer ID and label. +else: + print(response.json()) # new_contract is the rental instance ID ``` The same call with curl: diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index f3c36374..f329a5aa 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,19 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. For any other listing field you leave out, the CLI sends `null`, which overwrites the current setting. Always pass `-m` with the current `listed_min_gpu_count` (a null `min_chunk` is HTTP 400 `invalid_args`). Omitting `-l` clears auto-renew (`duration`); pass `-l` again to keep it. Omitting `-v` can create a volume offer at half the free disk; pass `-v 0` to skip that. There is no flag that keeps a listing hidden, so `vastai list machine` makes a hidden listing public. It also resets the storage price to the default ($0.10/GB/month) unless you pass `-s`. On a live listing, `-e` extends any active rental that ends before the new date, including SLA rentals. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. + +On an existing listing, omitted GPU price, bandwidth prices, reserved discount, and `end_date` are kept. These are not: + +- **Hidden listings become public.** There is no flag for `hidden_listing`. +- **`-e` / `-l` can extend active rentals,** including SLA contracts. Normal CLI output does not print that. Pass `--raw` and read `.results[0].upd_contracts`. +- **Storage price resets to $0.10/GB/month** unless you pass `-s`. +- **Auto-renew is cleared** unless you pass `-l` again. +- **Omitting `-v` can create a volume offer** at half the free disk. Pass `-v 0` to skip that. +- **`-m` is required.** Omitting it returns HTTP 400 `invalid_args`. +- **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. Use the [fleet REST loop](/host/sla-offers#fleet-sla-re-list) instead. + +See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. ## Usage @@ -76,7 +88,7 @@ We strongly recommend you test the machine first and only list when ready. Alway ```bash # On a live listing, -e extends active rentals that end sooner (including SLA). -# Reuse the current end date and storage price when you only want to reprice. +# Reuse the current end date, storage price, and min GPU count when you only want to reprice. vastai list machine -g 3.50 -s -m -v 0 -e # For an auto-renew listing, pass -l again instead of -e. ``` diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 4664c53f..8007103d 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so Claim and Confidence stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`. A later reprice through the SDK or CLI makes a hidden listing public and can reset storage price and auto-renew. Update hidden SLA listings with REST and send `hidden_listing` explicitly. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so Claim and Confidence stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. Pass `min_chunk` as well (null `min_chunk` is HTTP 400). Update hidden SLA listings with REST and send `hidden_listing` explicitly. ## Signature @@ -63,12 +63,13 @@ VastAI.list_machine( ```python from vastai import VastAI +import os client = VastAI(api_key="YOUR_API_KEY") -# Base listing only — for SLA, use the console or REST create_asks after list_machine() -# see SLA Offers → API (for automation): /host/sla-offers#api-for-automation -# On a live listing, end_date extends active rentals that end sooner (including SLA). -# Replace the numbers with this machine's listed_storage_cost, listed_min_gpu_count, and end_date. -result = client.list_machine(id=12345, price_gpu=3.50, price_disk=0.10, min_chunk=1, end_date=1790000000) +# Replace price_disk and min_chunk with this machine's current values. +# CURRENT_END_DATE_UNIX must be that machine's future end_date. A past value expires the offer. +# vol_size=0 avoids creating a volume offer. +CURRENT_END_DATE_UNIX = int(os.environ["CURRENT_END_DATE_UNIX"]) +result = client.list_machine(id=12345, price_gpu=3.50, price_disk=0.15, min_chunk=1, vol_size=0, end_date=CURRENT_END_DATE_UNIX) print(result) ``` From 021f980748c767f7707b53854c0d50eba03de387 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 21:01:51 -0700 Subject: [PATCH 177/250] docs(sla): address doc-review consensus (cycle 123) Match the console credit label to the Charges row, and document list_machine kwargs the SDK actually accepts. Co-authored-by: Cursor --- api-reference/permissions.mdx | 6 ++-- cli/reference/create-instance.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 34 ++++++++++++---------- guides/reference/billing.mdx | 2 +- sdk/python/reference/create-instance.mdx | 19 ++++++++++-- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 7 +++-- 7 files changed, 47 insertions(+), 25 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index c1730fe6..5ccd7cb8 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -95,7 +95,7 @@ You can create scoped keys using: Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. The itemized **Service Credit** line is only in the console. Charges `type: "sla"` is the SLA fee minus any service credit. +**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. Charges and **Account → Billing → Charges** show the same net `type: "sla"` row. The console labels it **Service Credit** only when the amount is negative. - Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. @@ -121,7 +121,7 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if | Rent with an SLA | `instance_write` | Console **RENT** | | Verify `target_reliability` | `instance_read` | **Instances** | -**Service credits:** An itemized **Service Credit** line appears only in the web console (**Account → Billing**). `GET /api/v0/charges/` requires `select_filters` with both `day.gte` and `day.lte` (unix seconds, UTC). A call without that range returns HTTP 400. The response can include `results[].items[]` rows with `type: "sla"` (description still **SLA Fee**). Each row is the **net** SLA settlement for settled days in the window: SLA fee minus any service credit. On a day with a credit the amount is smaller and can be negative. The row is omitted until the last day in the window has settled. Page by sending `next_token` as `after_token`. Stop when `next_token` is `null`. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. +**Service credits:** **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net row. The call requires `select_filters` with both `day.gte` and `day.lte` (unix seconds, UTC). A call without that range returns HTTP 400. The response can include `results[].items[]` rows with `type: "sla"`. Each row is the SLA fee minus any service credit. The console labels a negative amount **Service Credit** and any other amount **SLA Fee**. A credit smaller than the fee is a smaller **SLA Fee** row, not a separate line. The row is omitted until the last day in the window has settled. Page by sending `next_token` as `after_token`. Stop when `next_token` is `null`. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. ```bash curl -G "https://console.vast.ai/api/v0/charges/" \ @@ -130,7 +130,7 @@ curl -G "https://console.vast.ai/api/v0/charges/" \ ``` -Do not use the Charges API alone to reconcile service credits. The `sla` row is a net amount, not an itemized credit, and it is missing until the window has settled. +To reconcile a credit, compare each day's net `sla` row with the SLA fee you expected. A smaller or negative amount means a credit was applied. The row is missing until the window has settled. diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index fce9fbf1..e844e968 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -11,7 +11,7 @@ Create a new instance **SLA** - This command cannot set `target_reliability`. -- No **SLA Fee** line in the price breakdown means you do **not** have an SLA (even if search quoted SLA). +- No **SLA Fee** line on the Search offer, or on a **running** instance, means you do **not** have an SLA (even if search quoted SLA). The line is hidden while the instance is loading, stopped, or offline. - Enable SLA in the console: **Search filters** (left bar) → **Reliability target**, confirm **SLA fee**, then **RENT**—or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. - See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). Match `--disk` to any `--storage` you used in search. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 87cdf350..25952dca 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay an hourly **SLA fee** on top of compute, but only after you set a **reliability target** at rent time. The fee is usually small when your target is well below the host's reliability commitment. It can approach the GPU price when your target is close to that commitment. The console shows the fee as the **SLA Fee** line. API fields call it a premium (for example `slaPremiumPerHour`). A **service credit** is paid only when measured reliability falls below your target, and it is shown as **Service Credit** in Account → Billing. A short outage that stays above the target is billed with no credit. Search can show the price; it does not turn the SLA on by itself. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay an hourly **SLA fee** on top of compute, but only after you set a **reliability target** at rent time. The fee is usually small when your target is well below the host's reliability commitment. It can approach the GPU price when your target is close to that commitment. The console shows the fee as the **SLA Fee** line. API fields call it a premium (for example `slaPremiumPerHour`). A **service credit** is paid only when measured reliability falls below your target. In **Account → Billing → Charges**, and in `GET /api/v0/charges/`, that settlement is one net row (SLA fee minus any service credit). The console labels the row **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. A credit smaller than the fee shows up as a smaller **SLA Fee** row, not a separate line. A short outage that stays above the target is billed with no credit. Search can show the price; it does not turn the SLA on by itself. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -25,7 +25,7 @@ A few things people mix up: - The GPU bill does **not** stop during an outage. A credit is paid only when the blended measure falls below your target, usually after the next UTC midnight. A short outage that stays above the target is billed in full with no credit. - Filtering for SLA offers (`has_sla`, SLA-enabled), or a CLI or API search, does **not** turn on an SLA. Setting **Reliability target** in the console Search filters and then clicking **RENT**, or sending `target_reliability` on REST rent, does. The CLI cannot turn SLA on. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. -- If the price breakdown has **no SLA Fee line**, you do not have an SLA. In **Account → Billing** the same charge appears as **SLA Fee**, and credits as **Service Credit**. In API responses the hourly amount is `slaPremiumPerHour`. +- If the Search offer has **no SLA Fee line**, you do not have an SLA. On an instance, that line appears only while the instance is **running**. In **Account → Billing → Charges** the settlement row is labeled **Service Credit** only when the net amount is negative, and **SLA Fee** otherwise. In API responses the hourly amount is `slaPremiumPerHour`. Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). @@ -122,7 +122,7 @@ Search **quotes** SLA pricing. The SLA starts only when you set **Reliability ta 1. Open [Search](https://cloud.vast.ai/create/) and confirm **On-demand** is selected (SLA does not apply to interruptible rentals). 2. In Search filters (left filter bar), set **Reliability target** to your desired reliability target — for example **95%** or **99%**. If you do not set a target, you are not opting into SLA. 3. Optionally narrow results with an SLA-enabled / `has_sla` filter if shown. Filtering listings is **not** the same as enabling the SLA. -4. Before you click **RENT**, confirm the price breakdown shows an **SLA Fee** line. No SLA Fee line means that rental has no SLA. +4. Before you click **RENT**, confirm the offer card in Search shows an **SLA Fee** line. No SLA Fee line on that Search offer means the rental has no SLA. After you rent, the instance price details show the SLA Fee line only once the instance is **running**. While it is loading, stopped, or offline, a missing line does not mean the SLA failed. 5. **Disk before RENT:** Set instance disk on the console slider before **RENT**. If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 6. Rent as usual. Your target is locked at rent time. @@ -186,7 +186,7 @@ Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `d -Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. Service credits are not itemized in any API. In Charges, `type: "sla"` rows are the SLA fee minus any service credit (they can be negative) and appear only after the window settles. The itemized **Service Credit** line is only in the web console. Invoices and credit webhooks do not itemize it. +Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. Charges and the console Charges tab show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative. Invoices and credit webhooks do not include that row. @@ -198,7 +198,7 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ | Search / quote an SLA | Yes | Yes (`POST /api/v0/bundles/`) | | Enable an SLA at rent | Yes | Yes (`target_reliability` on `PUT /api/v0/asks/{id}/`) | | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | -| SLA service credits | **Account → Billing** (itemized **Service Credit**) | Charges `results[].items[].type` `sla` is the SLA fee minus any service credit, not an itemized credit. Not in invoices or client webhooks. | +| SLA settlement | **Account → Billing → Charges** (same net row as the API) | `results[].items[].type` `sla` is the SLA fee minus any service credit. The console labels a negative amount **Service Credit** and any other amount **SLA Fee**. Not in invoices or client webhooks. | **Rent body (SLA):** Among SLA-related fields, send only `target_reliability` (not `sla_r_claim` / `sla_r_target`). Still include `image` or `template_hash_id` and a `disk` that matches your search quote. @@ -277,14 +277,14 @@ curl -G "https://console.vast.ai/api/v1/instances/" \ --data-urlencode "limit=25" ``` -Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row. For the SLA fee: if the instance is not yet **running**, use `search.slaPremiumPerHour` (search-context pricing); once **running**, also check `instance.slaPremiumPerHour`. A missing `instance.slaPremiumPerHour` before startup is not a failed SLA rent. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, confirm you used `new_contract` (not the offer id), then retry after a short delay, no more than about once per second (`show_instances` `x-rate-limit` threshold `1.0`). Use `after_token` paging only when listing without an `id` filter. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). +Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row (`target_reliability > 0` means the rental has an SLA). `instance.slaPremiumPerHour` is `0` until the instance is **running**, so do not treat `0` before startup as a failed SLA rent. Once it is running, that field is the SLA fee. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, confirm you used `new_contract` (not the offer id), then retry after a short delay, no more than about once per second (`show_instances` `x-rate-limit` threshold `1.0`). Use `after_token` paging only when listing without an `id` filter. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). If you omit `limit`, the server returns at most **25** rows. A non-positive `limit` is treated as 5, then capped at 25. - **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. -**Billing reconciliation (console):** Verifying the SLA on an instance (for example via `GET /api/v1/instances/`) does not show service credits. After UTC settlement, open **Account → Billing** for the itemized **Service Credit**. `GET /api/v0/charges/` requires `select_filters` with `day.gte` and `day.lte` (unix seconds). `results[].items[]` with `type: "sla"` is the SLA fee minus any service credit (the description still says **SLA Fee**). It can be smaller or negative, and it is omitted until the last day in the window has settled. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. +**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. **Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour`. Show-instances uses OpenAPI threshold `1.0` (about one request per second). @@ -292,12 +292,12 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | --- | --- | --- | | Target outside `[0, 1)` (negative, or 1 or above) | HTTP 400 `invalid_args` ("target reliability must be greater than or equal to 0 and less than 1") | SLA requires `0 < target_reliability < 1`. Sending `0` or omitting the field rents **without** an SLA (HTTP 200, no error). | | Offer has no SLA, target is above the host commitment, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | -| SLA not enabled for the account or region | HTTP 403 `sla_disabled` | Contact support | +| SLA is temporarily disabled platform-wide | HTTP 403 `sla_disabled` | Retry later. While SLA is disabled, search ignores `target_reliability` and returns non-SLA prices. | | Offer no longer exists | HTTP 400 `invalid_args` (`msg` may contain `error 404/3603`), HTTP 404 `no_such_ask` (`msg` may contain `error 404/3659` if the offer was taken mid-request), or HTTP 410 | Re-search and use a fresh offer ID. Do not retry the same ID. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | -| Too many requests | HTTP 429. Detect throttling by the status code. The body differs by endpoint (JSON `msg`/`error` or plain text), so do not parse a `detail` field. Stay at or below about 10 search requests per minute per IP. If a `Retry-After` header is present, honor it. Space rent calls at least 5 seconds apart (threshold 4.5). OpenAPI `penalty: 12` on rent is seconds added to the server's last-request time, so a burst can block longer than that spacing. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Too many requests | HTTP 429. Detect throttling by the status code. The body differs by endpoint, so do not parse a `detail` field. Stay at or below about 10 search requests per minute per IP. If a `Retry-After` header is present, honor it. Space rent calls at least 5 seconds apart. A burst can block you for longer than that spacing. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message includes `error 403/3586` ("Hosts can only rent their own machines"). The HTTP status is 400, not 403. A host-only key gets this for every offer that is not on its own machines, including a missing offer. | Switch to a renter account key, then re-search (see [Hosting Overview](/host/hosting-overview) self-test note). | @@ -326,7 +326,11 @@ When you rent an SLA-backed offer **with a target set**: Billing continues during downtime. You are still charged for **compute, storage, and the SLA fee** while the contract exists and the instance is unavailable. Leaving a broken instance running continues those charges until you destroy it. -**This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and the service credit is the compensation for that downtime. + +During an outage the Instances price popover may say "Machine is offline. You're not being charged." That message does not apply to SLA rentals: compute, storage, and the SLA fee continue while the contract is active. + + +**This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and a service credit is paid only when the blended measure falls below your target. **Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. **Destroy** the instance when you are done. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Final SLA settlement still posts when the contract closes. @@ -365,7 +369,7 @@ Production settlement uses the multi-window reliability blend described above, n ### Settlement timing - Settlement runs **once per day** for the previous billing day (UTC). -- Service credits post to your **account balance**. View the itemized **Service Credit** under **Account → Billing**. Do not treat a Charges `type: "sla"` row as that line: it is the SLA fee minus any service credit. Do not use invoices to reconcile SLA credits. +- Service credits post to your **account balance**. In **Account → Billing → Charges**, a negative net SLA row is labeled **Service Credit**. Any other net is labeled **SLA Fee**. `GET /api/v0/charges/` returns that same net as `type: "sla"`. Do not use invoices to reconcile SLA credits. - When your contract ends, any remaining unsettled days are resolved at close. ## If your instance goes down @@ -381,8 +385,8 @@ Production settlement uses the multi-window reliability blend described above, n ### In the web console (active instances) 1. Open **Instances** and select your running instance. -2. Open **price details** (or the instance billing panel) and confirm an **SLA Fee** line is present. -3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. If you do not see a target or SLA fee, you likely rented without the SLA. +2. Open **price details** only after the instance is **running**. The **SLA Fee** line is hidden while it is loading, stopped, or offline. That does not mean the SLA is missing. +3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. No SLA Fee line on the Search offer, or on a **running** instance, means that rental has no SLA. ### API integrators @@ -440,9 +444,9 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing** and look for **Service Credit** — not in the instance price panel. Service credits are not itemized in the Charges API, invoices, or billing exports. A Charges `type: "sla"` row is the SLA fee minus any service credit, not that line. +**Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. The Charges API returns the same net. Invoices do not. -**API integrators:** Prefer **Account → Billing** for an itemized **Service Credit**. `GET /api/v0/charges/` → `results[].items[]` with `type: "sla"` (description **SLA Fee**) is the net SLA settlement for the window: fee minus credit. The amount can be negative. The row is omitted until the window's last day has settled. The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). +**API integrators:** **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net. `results[].items[]` with `type: "sla"` is the SLA fee minus any service credit. The console labels a negative amount **Service Credit** and any other amount **SLA Fee**. A row below the fee you expected means a credit was applied. The row is omitted until the window's last day has settled. The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). ## Related documentation diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index 96d2ce98..7ca9fa8e 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -149,7 +149,7 @@ At the bottom of your billing page, you will find an itemized table of your tran ![Invoices tab of the Transaction History table](/images/transaction-history-table-invoices.png) -You can also click the **Charges** tab to see an itemized table of all charges from your instances, storage volumes, and serverless workers. Clicking the dropdown arrow on any of these items will display a more complete breakdown of those charges by type, including GPU usage, reserved disk storage, and upload/download usage. +You can also click the **Charges** tab to see an itemized table of all charges from your instances, storage volumes, and serverless workers. Clicking the dropdown arrow on any of these items will display a more complete breakdown of those charges by type, including GPU usage, reserved disk storage, and upload/download usage. SLA rentals add one net row for the SLA fee minus any service credit. That row is labeled **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. ![Charges tab of the Transaction History table](/images/transaction-history-table-charges.png) diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index aae88393..091a8384 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create_instance" Create a new instance from an offer/ask ID returned by search. -**SLA:** `target_reliability` is not available on `create_instance()` today. If the instance price breakdown has no **SLA Fee** line, you do **not** have an SLA—even if search showed SLA pricing. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). +**SLA:** `target_reliability` is not available on `create_instance()` today. No **SLA Fee** line on the Search offer, or on a **running** instance, means you do **not** have an SLA—even if search showed SLA pricing. The line is hidden while the instance is loading, stopped, or offline. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). ## Signature @@ -204,7 +204,22 @@ try: timeout=60, ) response.raise_for_status() -except requests.RequestException: +except requests.HTTPError as exc: + status = exc.response.status_code if exc.response is not None else None + if status == 429 or status is None: + found = requests.get( + "https://console.vast.ai/api/v1/instances/", + params={"select_filters": json.dumps({"label": {"eq": label}})}, + headers=headers, + timeout=30, + ) + found.raise_for_status() + # If this returns no instance, re-search and PUT again with a new offer ID and label. + elif status in (400, 403, 404, 410): + raise + else: + raise +except (requests.Timeout, requests.ConnectionError): found = requests.get( "https://console.vast.ai/api/v1/instances/", params={"select_filters": json.dumps({"label": {"eq": label}})}, diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index f329a5aa..ddda8e9b 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -13,7 +13,7 @@ On an existing listing, omitted GPU price, bandwidth prices, reserved discount, - **Auto-renew is cleared** unless you pass `-l` again. - **Omitting `-v` can create a volume offer** at half the free disk. Pass `-v 0` to skip that. - **`-m` is required.** Omitting it returns HTTP 400 `invalid_args`. -- **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. Use the [fleet REST loop](/host/sla-offers#fleet-sla-re-list) instead. +- **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores missing SLA listings. It does not change prices. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 8007103d..333505f7 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so Claim and Confidence stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. Pass `min_chunk` as well (null `min_chunk` is HTTP 400). Update hidden SLA listings with REST and send `hidden_listing` explicitly. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so Claim and Confidence stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. To keep auto-renew, pass `duration` again (seconds or a string such as `"30 days"`) on every call. Never pass `duration` together with `end_date`. `end_date` accepts a date string or a Unix timestamp. Pass `min_chunk` as well (null `min_chunk` is HTTP 400). Update hidden SLA listings with REST and send `hidden_listing` explicitly. ## Signature @@ -17,7 +17,10 @@ VastAI.list_machine( price_inetd: Optional[float] = None, discount_rate: Optional[float] = None, min_chunk: Optional[int] = None, - end_date: Optional[str] = None, + end_date: Optional[Union[str, int, float]] = None, + duration: Optional[str] = None, + vol_size: Optional[int] = None, + vol_price: Optional[float] = None, ) -> str ``` From 6e795b90d0312040478218d5bbdb18b90c9721da Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 21:07:52 -0700 Subject: [PATCH 178/250] docs(sla): address doc-review consensus (cycle 124) Let renters read SLA credits from Charges, and stop the hosting overview from hiding end-date extensions. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 10 +++--- host/hosting-overview.mdx | 8 +++-- sdk/python/reference/create-instance.mdx | 42 +++++++++++----------- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 25952dca..9d2bb7d4 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -54,7 +54,7 @@ Full steps: [In the web console](#in-the-web-console). CLI/API limits for automa | I use the CLI for search | [CLI for search only](#cli-for-search-only) → console or REST to enable SLA at rent | | Understand charges and credits | [How pricing works](#how-pricing-works) → [What happens after you rent](#what-happens-after-you-rent) | | Automate search → rent → verify | [API automation](#api-automation) | -| View service credits | **Account → Billing** (console only today) | +| View service credits | **Account → Billing → Charges**, or `GET /api/v0/charges/` (`billing_read`) | **Console renters (web only).** You do not need an API key. Follow [In the web console](#in-the-web-console), skip [API automation](#api-automation), and continue at [What happens after you rent](#what-happens-after-you-rent) for outage billing and credits. @@ -284,15 +284,15 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. -**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. +**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. -**Automation limitations:** SLA service credits are reconciled in the console (**Account → Billing**). There is no renter API, export, or webhook for those credit line items today. After the UTC day boundary (wait up to about 48 hours if a line is missing), check billing or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour`. Show-instances uses OpenAPI threshold `1.0` (about one request per second). +**Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read the same net `type: "sla"` row from **Account → Billing → Charges** or `GET /api/v0/charges/` (see the billing reconciliation paragraph above). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). | Symptom | Typical response | What to do | | --- | --- | --- | | Target outside `[0, 1)` (negative, or 1 or above) | HTTP 400 `invalid_args` ("target reliability must be greater than or equal to 0 and less than 1") | SLA requires `0 < target_reliability < 1`. Sending `0` or omitting the field rents **without** an SLA (HTTP 200, no error). | | Offer has no SLA, target is above the host commitment, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | -| SLA is temporarily disabled platform-wide | HTTP 403 `sla_disabled` | Retry later. While SLA is disabled, search ignores `target_reliability` and returns non-SLA prices. | +| SLA not available | HTTP 403 `sla_disabled` | SLA is not enabled for this request. It may be off platform-wide or for this account. Do not retry in a loop. Rent without a reliability target, or contact support. | | Offer no longer exists | HTTP 400 `invalid_args` (`msg` may contain `error 404/3603`), HTTP 404 `no_such_ask` (`msg` may contain `error 404/3659` if the offer was taken mid-request), or HTTP 410 | Re-search and use a fresh offer ID. Do not retry the same ID. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | @@ -377,7 +377,7 @@ Production settlement uses the multi-window reliability blend described above, n 1. Save work and check **Instances** for host/maintenance status. 2. Remember: compute, storage, and SLA fees continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. 3. **Console:** Open **Instances**, select the instance, then **Destroy** to end charges on an unavailable SLA instance. See [Stop vs destroy](#what-you-pay-during-an-outage). Destroy deletes the disk, so copy off anything you need first. -4. After settlement, check **Account → Billing** in the console for SLA line items (not `GET /api/v0/charges/`). +4. After the UTC day settles, check **Account → Billing → Charges** or `GET /api/v0/charges/` for the net SLA row. Invoices do not show SLA credits. 5. If credits still look wrong **48 hours** after the outage day, contact support via [Discord](https://discord.gg/hSuEbSQ4X8) or [contact@vast.ai](mailto:contact@vast.ai). ## Viewing SLA on active instances diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index d840026a..73a80b7b 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -82,14 +82,14 @@ You can set the offer end date in the hosting interface by clicking on the date #### How the offer becomes a rental contract -When a client rents an instance from your offer, all of the offer's terms at that moment, the offer end date, the pricing, and the hardware specs, are locked into a **rental contract**. The offer end date becomes the contract's **rental end date** (shown in the UI as "client end date"), and the pricing becomes the contract's rate. Once created, a rental contract's terms cannot be changed, not by modifying the offer, not by unlisting the machine, and not by any other host action. +When a client rents an instance from your offer, all of the offer's terms at that moment, the offer end date, the pricing, and the hardware specs, are locked into a **rental contract**. The offer end date becomes the contract's **rental end date** (shown in the UI as "client end date"), and the pricing becomes the contract's rate. Once created, price and SLA terms stay locked. Unlisting or editing the offer does not change them. **One exception:** sending an offer end date, at the same or lower price, extends every active rental that ends before that date. See [Extending rental contracts](#extending-rental-contracts). #### Can I change the offer? Yes, but changes only affect future rental contracts. Existing rental contracts keep their original terms: - **Changing the price** does not change the rate on any existing rental contract -- **Shortening** the offer end date limits the commitment window for new clients, but does not shorten any existing rental end date +- **Shortening** the offer end date limits the commitment window for new clients, but does not shorten any existing rental end date. Any end date you send, including an earlier one, still extends active rentals that end before it, unless the same change raises the GPU, disk, or bandwidth price. To stop new rentals without extending anything, unlist instead. - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates @@ -162,9 +162,11 @@ By default, volume offers will be listed with GPU offers at the same disk price Space is listed in Gigabytes, and price in \$/Gb/Month. ```text Text -vastai list machine -v -z -g .5 -e -r 0 -m 1 +vastai list machine -v -z -g -s -m -e ``` +Omitted flags reset values on an existing listing, and `-e` extends active rentals that end before the new date, including SLA rentals. Read the [`list machine` caveats](/host/cli/list-machine) and [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts) first. + You can also directly create a volume offer by running the `vastai list volume` command. ```text Text diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 091a8384..917ed92f 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -185,6 +185,7 @@ print(result) ```python import json +import time import requests offer_id = 12345 # path id: offer/ask ID from search, not a running instance ID @@ -196,6 +197,17 @@ body = { "target_reliability": 0.95, "label": label, } + +def instances_for_label(): + found = requests.get( + "https://console.vast.ai/api/v1/instances/", + params={"select_filters": json.dumps({"label": {"eq": label}})}, + headers=headers, + timeout=30, + ) + found.raise_for_status() + return found.json().get("instances") or [] + try: response = requests.put( f"https://console.vast.ai/api/v0/asks/{offer_id}/", @@ -206,28 +218,18 @@ try: response.raise_for_status() except requests.HTTPError as exc: status = exc.response.status_code if exc.response is not None else None - if status == 429 or status is None: - found = requests.get( - "https://console.vast.ai/api/v1/instances/", - params={"select_filters": json.dumps({"label": {"eq": label}})}, - headers=headers, - timeout=30, - ) - found.raise_for_status() - # If this returns no instance, re-search and PUT again with a new offer ID and label. - elif status in (400, 403, 404, 410): - raise - else: + if status in (400, 403, 404, 410): raise + retry_after = 5 + if exc.response is not None and str(exc.response.headers.get("Retry-After", "")).isdigit(): + retry_after = int(exc.response.headers["Retry-After"]) + time.sleep(retry_after) + if not instances_for_label(): + raise # no rental: re-search and PUT again with a new offer ID and label except (requests.Timeout, requests.ConnectionError): - found = requests.get( - "https://console.vast.ai/api/v1/instances/", - params={"select_filters": json.dumps({"label": {"eq": label}})}, - headers=headers, - timeout=30, - ) - found.raise_for_status() - # If this returns no instance, re-search and PUT again with a new offer ID and label. + time.sleep(5) + if not instances_for_label(): + raise # no rental: re-search and PUT again with a new offer ID and label else: print(response.json()) # new_contract is the rental instance ID ``` From d4441f6b1db18a15a362e71544971ba7af6bca47 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 21:16:23 -0700 Subject: [PATCH 179/250] docs(sla): address doc-review consensus (cycle 125) Poll for an existing rental before a second SLA rent, and skip fleet re-lists that are still in search. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-offers.mdx | 11 +++++--- sdk/python/reference/create-instance.mdx | 30 ++++++++++++---------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 9d2bb7d4..0d120da8 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -332,7 +332,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and a service credit is paid only when the blended measure falls below your target. -**Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. **Destroy** the instance when you are done. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Final SLA settlement still posts when the contract closes. +**Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. **Destroy** the instance when you are done. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 42370f10..4e18b7cc 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -39,7 +39,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. -2. Publish once **without** SLA (leave Claim at `0`) and test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. +2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** at `0`, **Save**, then click **LIST**. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. @@ -130,7 +130,7 @@ Over many strong days, SLA fees can offset occasional credits, but a single bad SLA reliability is measured at the **rental contract (instance) level** using platform health signals for active on-demand contracts — not your personal SSH session or Jupyter tab. -- **Instance fails to start** when a client rents → counts against SLA reliability for that contract. +- **Instance fails to start** because the machine is down (driver, disk, network, or daemon) → counts against SLA reliability for that contract. Whether downtime the renter causes (their own Stop or reboot, a bad image, a container crash, or a stop at zero balance) counts against you, or earns them a credit, is not specified. Contact support before you treat that downtime as yours. - **Machine-level outage** while contracts are active → affects settlement for those contracts. - **Brief host reboots** during active rentals may count as downtime. Vast does not publish a fixed second-level threshold in host docs — treat unplanned reboots as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance) with at least 24 hours' notice when possible. - **Scheduled maintenance** may be partly forgiven (counted as uptime) — see [Scheduled maintenance](#scheduled-maintenance). That is not a service credit. @@ -437,6 +437,11 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then echo "skip $id: not in ALLOWLIST"; continue fi + # Fully rented machines are also absent from search. Confirm on Host → Machines before you treat a miss as an outage. + if vastai search offers "machine_id=$id verified=any has_sla=true" --raw --api-key "$VAST_API_KEY" \ + | jq -e 'type == "array" and length > 0' >/dev/null; then + echo "skip $id: SLA offer still in search"; continue + fi machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') if ! echo "$machine" | jq -e '.listed == true' >/dev/null; then @@ -733,7 +738,7 @@ On SLA rentals, compute pay and the SLA fee are released together as SLA earning After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). -For SLA contracts, `sla_earn` is the escrow released to you that day. It matches the backtester's `escrow_to_host_balance`. Releases are spread over time rather than paid out the same day, so an early or low day can reflect release timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. +For SLA contracts, `sla_earn` is the escrow released to you that day. It is not a per-contract list of service credits. A lower value can be release timing rather than a credit. For a breakdown on one contract, contact support. It matches the backtester's `escrow_to_host_balance` only when that machine's only rental that day was a single SLA contract at the simulated target. Releases are spread over time rather than paid out the same day, so an early or low day can reflect release timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 917ed92f..50184dcb 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -217,21 +217,25 @@ try: ) response.raise_for_status() except requests.HTTPError as exc: - status = exc.response.status_code if exc.response is not None else None - if status in (400, 403, 404, 410): + status = exc.response.status_code if exc.response is not None else 0 + if status != 429 and 400 <= status < 500: raise - retry_after = 5 - if exc.response is not None and str(exc.response.headers.get("Retry-After", "")).isdigit(): - retry_after = int(exc.response.headers["Retry-After"]) - time.sleep(retry_after) - if not instances_for_label(): - raise # no rental: re-search and PUT again with a new offer ID and label except (requests.Timeout, requests.ConnectionError): - time.sleep(5) - if not instances_for_label(): - raise # no rental: re-search and PUT again with a new offer ID and label -else: - print(response.json()) # new_contract is the rental instance ID + pass + +time.sleep(5) +contract_id = None +for _ in range(5): + rows = instances_for_label() + if rows: + contract_id = rows[0].get("id") + break + time.sleep(1) +if contract_id is None: + raise RuntimeError( + "No instance for this label. Re-search and PUT again with a new offer id and label." + ) +print(contract_id) ``` The same call with curl: From 5537e9531a56544d13f26f94ae121df111ef4934 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 21:25:05 -0700 Subject: [PATCH 180/250] docs(sla): address doc-review consensus (cycle 126) Fail closed when fleet search errors, so a live re-list cannot extend healthy SLA contracts. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-offers.mdx | 24 ++++++++++++++++------ sdk/python/reference/create-instance.mdx | 24 ++++++++++++---------- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 5ccd7cb8..c5c7a017 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -126,11 +126,11 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if ```bash curl -G "https://console.vast.ai/api/v0/charges/" \ -H "Authorization: Bearer $VAST_API_KEY" \ - --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1769903999}}' + --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1767311999}}' ``` -To reconcile a credit, compare each day's net `sla` row with the SLA fee you expected. A smaller or negative amount means a credit was applied. The row is missing until the window has settled. +Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). A smaller or negative amount than the SLA fee you expected means a credit was applied. The row is missing until that day has settled. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 0d120da8..c1750cac 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -37,7 +37,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 2. In **Search filters** (left bar), set **Reliability target**. 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown, then click **RENT**. -5. Right after **RENT**, verify under **Instances**: open **price details** and confirm an **SLA Fee** line and your reliability target (see [Viewing SLA on active instances](#viewing-sla-on-active-instances)). +5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. 6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing**. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). @@ -374,7 +374,7 @@ Production settlement uses the multi-window reliability blend described above, n ## If your instance goes down -1. Save work and check **Instances** for host/maintenance status. +1. If you can still reach the instance, save work. If the machine is offline, you may not be able to copy data off it. You can wait (compute, storage, and the SLA fee keep billing; a credit applies only if that day's blended measure falls below your target) or **Destroy** (charges stop and the disk is deleted). Check **Instances** for host or maintenance status. 2. Remember: compute, storage, and SLA fees continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. 3. **Console:** Open **Instances**, select the instance, then **Destroy** to end charges on an unavailable SLA instance. See [Stop vs destroy](#what-you-pay-during-an-outage). Destroy deletes the disk, so copy off anything you need first. 4. After the UTC day settles, check **Account → Billing → Charges** or `GET /api/v0/charges/` for the net SLA row. Invoices do not show SLA credits. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 4e18b7cc..fc8c2117 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -383,7 +383,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. You cannot see per-contract end dates beforehand. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). -Run this only when an SLA listing is missing from search after a daemon update even though **Set Pricing** still shows SLA. A fully rented machine is absent from search too. Do not re-list it for that reason. Healthy listings do not need a re-list, and every re-list can extend shorter active contracts. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. +The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute per IP. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented, so confirm **Host → Machines** before `DRY_RUN=0`. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. `show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. @@ -418,6 +418,7 @@ This example is illustrative: it sleeps between machines and logs success/error ```bash : "${VAST_API_KEY:?export VAST_API_KEY first (needs machine_write and machine_read)}" +: "${SEARCH_API_KEY:?export SEARCH_API_KEY first (needs misc, on its own key)}" # Leave DRY_RUN=1 until you confirm each machine is **Listed** (or on your allowlist). # Set DRY_RUN=0 to apply. # ALLOWLIST required for DRY_RUN=0 (space-separated listed machine IDs). @@ -437,11 +438,22 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then echo "skip $id: not in ALLOWLIST"; continue fi - # Fully rented machines are also absent from search. Confirm on Host → Machines before you treat a miss as an outage. - if vastai search offers "machine_id=$id verified=any has_sla=true" --raw --api-key "$VAST_API_KEY" \ - | jq -e 'type == "array" and length > 0' >/dev/null; then - echo "skip $id: SLA offer still in search"; continue + # A failed search must not become a PUT. Fully rented machines are also absent from search. + sleep 6 + if ! out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --api-key "$SEARCH_API_KEY" 2>/dev/null); then + echo "skip $id: search failed (missing misc permission or HTTP 429)" >&2 + continue + fi + if ! printf '%s' "$out" | jq -e 'type == "array"' >/dev/null; then + echo "skip $id: search returned non-array output" >&2 + continue + fi + if printf '%s' "$out" | jq -e 'length > 0' >/dev/null; then + echo "skip $id: SLA offer still in search" >&2 + continue fi + # Empty array: the offer is not in search. A fully rented machine looks the same. + # Confirm on Host → Machines before DRY_RUN=0. Do not re-list it only because search is empty. machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') if ! echo "$machine" | jq -e '.listed == true' >/dev/null; then @@ -711,7 +723,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m - **Listing rejected (`invalid_sla_params`)** — Re-check the reliability commitment and `sla_sigma_x` against [validation rules](#validation-rules). - **`sla_not_approved`** — Contact support; you can keep a non-SLA listing while approval is pending. - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. -- **Unexpected credit** — Review reliability; re-run the backtester over the affected dates and check `escrow_to_client_balance` and `reliability` on those days. +- **Unexpected credit** — `sla_earn` is not a per-contract credit record, and the backtester is an estimate, not the settlement. Contact support with the machine ID and the UTC dates. - **Severe outage (active SLA contracts):** 1. **Save your current terms before you unlist.** After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, and SLA terms. The snapshot does not include confidence (`sla_sigma_x`; only the `sla_confidence` label) or hidden status (`hidden_listing`). Write both down either way. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 50184dcb..4d3c2ee8 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -216,24 +216,26 @@ try: timeout=60, ) response.raise_for_status() + contract_id = response.json().get("new_contract") except requests.HTTPError as exc: status = exc.response.status_code if exc.response is not None else 0 if status != 429 and 400 <= status < 500: raise + contract_id = None except (requests.Timeout, requests.ConnectionError): - pass - -time.sleep(5) -contract_id = None -for _ in range(5): - rows = instances_for_label() - if rows: - contract_id = rows[0].get("id") - break - time.sleep(1) + contract_id = None + +if contract_id is None: + time.sleep(5) + for _ in range(5): + rows = instances_for_label() + if rows: + contract_id = rows[0].get("id") + break + time.sleep(1) if contract_id is None: raise RuntimeError( - "No instance for this label. Re-search and PUT again with a new offer id and label." + "No instance for this label. Do not PUT again until you have checked Instances." ) print(contract_id) ``` From f0394995421d2b8bf069d1ccfd85a56f40175316 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 21:33:35 -0700 Subject: [PATCH 181/250] docs(sla): address doc-review consensus (cycle 127) Skip fleet re-lists when a machine still has running rentals, so an empty search cannot extend them. Co-authored-by: Cursor --- host/sla-offers.mdx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index fc8c2117..5fa6b882 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -383,7 +383,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. You cannot see per-contract end dates beforehand. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). -The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute per IP. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented, so confirm **Host → Machines** before `DRY_RUN=0`. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. +The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute per IP. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_running` is `0`, because a PUT that resends `end_date` extends every shorter rental and its credit exposure. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has free GPUs. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. `show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. @@ -452,8 +452,6 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: SLA offer still in search" >&2 continue fi - # Empty array: the offer is not in search. A fully rented machine looks the same. - # Confirm on Host → Machines before DRY_RUN=0. Do not re-list it only because search is empty. machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') if ! echo "$machine" | jq -e '.listed == true' >/dev/null; then @@ -486,6 +484,12 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: SLA enabled but no stored confidence; set sla_sigma_x first" >&2 continue fi + # An empty search usually means every GPU is rented. The PUT resends end_date + # or duration and extends every shorter active rental. Skip unless the rental count is 0. + if ! echo "$machine" | jq -e 'has("current_rentals_running") and .current_rentals_running == 0' >/dev/null; then + echo "skip $id: active rentals or rental count unavailable (PUT would extend them)" >&2 + continue + fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. # price_disk is required: null or omitted resets storage price to 0.10. # Rolling (-l) listings are included. Resend duration as an integer (whole seconds) so auto-renew stays on. @@ -742,7 +746,7 @@ Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `m 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. When you relist, use the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. If the snapshot lacks the discount or min bid, use the console notes. Relisting creates a new ask, and an omitted `credit_discount_max` becomes `0.4`. Send `sla_sigma_x` explicitly; a new ask otherwise defaults to 0.5. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. If the snapshot lacks the discount or min bid, use the console notes. Relisting creates a new ask, and an omitted `credit_discount_max` becomes `0.4`. Send `sla_sigma_x` explicitly; a new ask otherwise defaults to 0.5. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing From dc821439e247aede447444016f9d1e91e4f6288b Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 21:44:43 -0700 Subject: [PATCH 182/250] docs(sla): address doc-review consensus (cycle 128) Gate fleet re-lists on resident rentals, including stopped ones, and search only after local checks. Co-authored-by: Cursor --- api-reference/openapi.yaml | 3 +- api-reference/openapi/yaml/list_machine.yaml | 3 +- guides/instances/choosing/sla-coverage.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 48 +++++++++++--------- 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index dbf20162..3a2516b0 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4713,7 +4713,7 @@ paths: example: Your key lacks the machine_write permission group '403': description: "Forbidden \u2014 machine locked, host not approved for SLA,\ - \ or daemon too old for SLA" + \ SLA switched off platform-wide, or daemon too old for SLA" content: application/json: schema: @@ -4724,6 +4724,7 @@ paths: enum: - machine_locked - sla_not_approved + - sla_disabled - sla_daemon_outdated example: machine_locked msg: diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index d6f9008f..4bbc15d7 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -185,7 +185,7 @@ paths: type: string example: Your key lacks the machine_write permission group '403': - description: Forbidden — machine locked, host not approved for SLA, or daemon too old for SLA + description: Forbidden — machine locked, host not approved for SLA, SLA switched off platform-wide, or daemon too old for SLA content: application/json: schema: @@ -196,6 +196,7 @@ paths: enum: - machine_locked - sla_not_approved + - sla_disabled - sla_daemon_outdated example: machine_locked msg: diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c1750cac..bdb3f081 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -284,7 +284,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. -**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. +**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Each Charges row is one contract. Match `source` to `instance-` plus the contract ID from `new_contract` (or `metadata.label` if you set a unique label at rent), then read the `sla` item in `items[]`. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. **Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read the same net `type: "sla"` row from **Account → Billing → Charges** or `GET /api/v0/charges/` (see the billing reconciliation paragraph above). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 73a80b7b..5b9d12ce 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -252,7 +252,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. - **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. -- **SLA rentals:** unlist, the same as above. Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **SLA rentals:** unlist, the same as above. **Before you unlist**, write down your current terms ([Severe outage step 1](/host/sla-offers#when-things-go-wrong)). After unlist, `show machines` no longer returns them. Relisting creates a new ask with no SLA and default settings, so re-enter Claim and Confidence before you **LIST** ([step 6](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 5fa6b882..38b71d9d 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -383,7 +383,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. You cannot see per-contract end dates beforehand. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). -The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute per IP. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_running` is `0`, because a PUT that resends `end_date` extends every shorter rental and its credit exposure. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has free GPUs. It does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. +The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute per IP. The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. `show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. @@ -410,7 +410,7 @@ For multiple machines, loop sequentially — do not parallelize without backoff: 1. Skip machines missing base pricing fields. 2. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields (preserve existing reliability commitment and confidence when set). 3. Space requests at least 5 seconds apart (`sleep 5` in the example; `create_asks` has an `x-rate-limit` threshold of `5.0`). At fleet scale, detect HTTP **429** and retry that machine with backoff before treating it as failed—do not rerun the whole loop with `DRY_RUN=0` until transient rate limits clear. -4. On `invalid_sla_params`, `sla_not_approved`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. +4. On `invalid_sla_params`, `sla_not_approved`, `sla_disabled`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. @@ -438,20 +438,6 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then echo "skip $id: not in ALLOWLIST"; continue fi - # A failed search must not become a PUT. Fully rented machines are also absent from search. - sleep 6 - if ! out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --api-key "$SEARCH_API_KEY" 2>/dev/null); then - echo "skip $id: search failed (missing misc permission or HTTP 429)" >&2 - continue - fi - if ! printf '%s' "$out" | jq -e 'type == "array"' >/dev/null; then - echo "skip $id: search returned non-array output" >&2 - continue - fi - if printf '%s' "$out" | jq -e 'length > 0' >/dev/null; then - echo "skip $id: SLA offer still in search" >&2 - continue - fi machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') if ! echo "$machine" | jq -e '.listed == true' >/dev/null; then @@ -484,10 +470,24 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: SLA enabled but no stored confidence; set sla_sigma_x first" >&2 continue fi - # An empty search usually means every GPU is rented. The PUT resends end_date - # or duration and extends every shorter active rental. Skip unless the rental count is 0. - if ! echo "$machine" | jq -e 'has("current_rentals_running") and .current_rentals_running == 0' >/dev/null; then - echo "skip $id: active rentals or rental count unavailable (PUT would extend them)" >&2 + # current_rentals_running ignores stopped instances. extend_cur_conts still + # extends every shorter contract, so gate on resident count (includes stopped). + if ! echo "$machine" | jq -e 'has("current_rentals_resident") and .current_rentals_resident == 0' >/dev/null; then + echo "skip $id: has rentals (including stopped) or current_rentals_resident missing" >&2 + continue + fi + # A failed search must not become a PUT. Fully rented machines are also absent from search. + sleep 6 + if ! out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --api-key "$SEARCH_API_KEY" 2>/dev/null); then + echo "skip $id: search failed (missing misc permission or HTTP 429)" >&2 + continue + fi + if ! printf '%s' "$out" | jq -e 'type == "array"' >/dev/null; then + echo "skip $id: search returned non-array output" >&2 + continue + fi + if printf '%s' "$out" | jq -e 'length > 0' >/dev/null; then + echo "skip $id: SLA offer still in search" >&2 continue fi # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. @@ -543,6 +543,7 @@ Replace `CURRENT_END_DATE_UNIX` and `CURRENT_MIN_CHUNK` with the current values | 401 | `success: false` + `msg` (+ optional `error`) | Missing `machine_write` or other required permission | | 403 | `machine_locked` | Machine is decommissioned or migration-locked | | 403 | `sla_not_approved` | Host account is not approved to create SLA asks | +| 403 | `sla_disabled` | SLA is switched off platform-wide. Do not retry in a loop. | | 403 | `sla_daemon_outdated` | Machine daemon build is too old for SLA listing | | 400 | `invalid_args` | Machine ID not found for your account, or malformed / incompatible request body | | 400 | `invalid_sla_params` | SLA parameters failed validation | @@ -722,10 +723,15 @@ Maintenance forgiveness is not guaranteed. Advance notice and window length dete Use the [SLA Earnings Backtester](/host/sla-backtester) (API-only; requires a `machine_read` API key) to replay historical earnings through SLA math. Console-only hosts can use the web console SLA preview and the economics walkthrough on this page instead. +## Getting help with SLA + +SLA approval, settlement questions, credit disputes, and locked machines are separate from machine setup. Contact support on [Discord](https://discord.gg/hSuEbSQ4X8) or at [contact@vast.ai](mailto:contact@vast.ai). Include the machine ID, the instance or contract ID, the UTC date, and the JSON error body or `upd_contracts` output if you have it. + ## When things go wrong - **Listing rejected (`invalid_sla_params`)** — Re-check the reliability commitment and `sla_sigma_x` against [validation rules](#validation-rules). -- **`sla_not_approved`** — Contact support; you can keep a non-SLA listing while approval is pending. +- **`sla_not_approved`** — See [Getting help with SLA](#getting-help-with-sla). You can keep a non-SLA listing while approval is pending. +- **`sla_disabled`** — SLA is off platform-wide. Do not retry in a loop. See [Getting help with SLA](#getting-help-with-sla). - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — `sla_earn` is not a per-contract credit record, and the backtester is an estimate, not the settlement. Contact support with the machine ID and the UTC dates. - **Severe outage (active SLA contracts):** From 729b5b18ea5be288a887df7c4df68214d4714f05 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 21:54:00 -0700 Subject: [PATCH 183/250] docs(sla): address doc-review consensus (cycle 129) Align planned-maintenance steps and say SLA downtime bills GPU, storage, and the fee, not only storage. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 6 +++--- guides/reference/billing.mdx | 4 ++-- guides/reference/faq/billing.mdx | 4 ++-- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 6 ++++-- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index bdb3f081..6d9096fa 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -330,9 +330,9 @@ Billing continues during downtime. You are still charged for **compute, storage, During an outage the Instances price popover may say "Machine is offline. You're not being charged." That message does not apply to SLA rentals: compute, storage, and the SLA fee continue while the contract is active. -**This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for the intended compute, and a service credit is paid only when the blended measure falls below your target. +**This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. -**Stop vs destroy:** While an SLA instance is unavailable, you are billed for intended compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. **Destroy** the instance when you are done. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. +**Stop vs destroy:** While an SLA instance is unavailable, you are billed for GPU compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. **Destroy** the instance when you are done. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. @@ -358,7 +358,7 @@ Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host re | Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (credit after the SLA fee) | | Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | -**How to read “Credit minus SLA fee”:** this column is only the service credit minus the SLA fee. It is not your net versus a non-SLA rental. On an SLA rental, offline time is still billed as intended compute. On a non-SLA rental it is not, so add that billed downtime when you compare the two. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day where the **blended measure** meets your target does not pay a credit. Raw daily uptime can sit at or slightly above the target while the blended measure is still below it. +**How to read “Credit minus SLA fee”:** this column is only the service credit minus the SLA fee. It is not your net versus a non-SLA rental. On an SLA rental, offline time is still billed as GPU compute, storage, and the SLA fee. On a non-SLA rental it is not, so add that billed downtime when you compare the two. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day where the **blended measure** meets your target does not pay a credit. Raw daily uptime can sit at or slightly above the target while the blended measure is still below it. Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index 7ca9fa8e..cfbbd054 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -21,7 +21,7 @@ Once your credits reach \$0.00, your instances, storage volumes, and data **will **When your balance reaches zero (or below):** - Your instances are **stopped automatically**. If you rent with an SLA, a stop at zero balance is not guaranteed to end the GPU charge or the SLA fee. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. - - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. + - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. On an SLA rental, storage is not the only charge that can continue: a zero-balance stop is not guaranteed to end the GPU charge or the SLA fee. See the first bullet. - To protect accounts with established usage history, **the system allows a short grace period where your balance may go negative before deletion occurs** -- the length of this buffer is calculated based on your account's average daily spend. Accounts with higher historical spend receive a proportionally larger buffer. **What happens next depends on whether you have a payment method on file:** @@ -82,7 +82,7 @@ You are charged the base active rental cost for every second your instance is in You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals are billed for intended compute during downtime. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals keep billing for GPU compute, storage, and the SLA fee during downtime, as if the instance were still running. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). To see a pricing breakdown on your current instances within your Instance page in the console or from offers on the Search page you can hover over the price to see pricing details. diff --git a/guides/reference/faq/billing.mdx b/guides/reference/faq/billing.mdx index 049b5a3d..46cd9c67 100644 --- a/guides/reference/faq/billing.mdx +++ b/guides/reference/faq/billing.mdx @@ -11,7 +11,7 @@ description: Questions about billing and credits Once you enter a credit card and an email address and both are verified you can then increase your credit balance using one-time payments with the add credit button. Whenever your credit balance hits zero or below, your instances will be stopped automatically, but not destroyed. -You are still charged storage costs for stopped instances, so it is important to destroy instances when you are done using them. +You are still charged storage costs for stopped instances, so it is important to destroy instances when you are done using them. On an SLA rental, a stop (including a stop at zero balance) is not guaranteed to end the GPU charge or the SLA fee. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). Your credit card will be automatically charged periodically to pay off any outstanding negative balance. @@ -33,7 +33,7 @@ You are charged the storage cost (which depends on the size of your storage allo Stopping an instance does not avoid storage costs. You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals are billed for intended compute during downtime. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals keep billing for GPU compute, storage, and the SLA fee during downtime, as if the instance were still running. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). ### What is the billing frequency? diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 5b9d12ce..c902b7ae 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -252,7 +252,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. - **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. -- **SLA rentals:** unlist, the same as above. **Before you unlist**, write down your current terms ([Severe outage step 1](/host/sla-offers#when-things-go-wrong)). After unlist, `show machines` no longer returns them. Relisting creates a new ask with no SLA and default settings, so re-enter Claim and Confidence before you **LIST** ([step 6](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance at least 24 hours ahead. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It only stops new rentals, and it removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter Claim and Confidence before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 38b71d9d..180670fe 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -39,7 +39,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. -2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** at `0`, **Save**, then click **LIST**. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. +2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** at `0`, **Save**, then click **LIST**. If you do not see an SLA or Claim section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. @@ -227,6 +227,8 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts +On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. + When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. Raising the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -240,7 +242,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover **New machine?** Complete [SLA host checklist](#sla-host-checklist) steps 1–2 first (list and test **without** SLA). Then set SLA here. 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. -2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. +2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. On a machine that already has rentals, moving the offer end date later extends every shorter SLA rental and your credit exposure. To avoid that, unlist instead of extending. See [SLA on extended contracts](#sla-on-extended-contracts). 3. Expand **SLA**. 4. Set your **reliability commitment** (the console control is **Claim**; the API field is `sla_r_claim`). Renters see it as expected reliability on the offer. Set **Confidence** too. For a new or volatile machine, start with **Wide**. Wider confidence charges a higher SLA fee, which is a cushion against credits; it does not reduce what you owe when a day misses the target. Move to **Normal** (`sla_sigma_x ≈ 0.5`) once uptime is stable. See [Confidence values](#confidence-values). 5. Confirm the SLA fee preview, then click **Save**. On an already-listed machine, **Save** publishes SLA immediately. From b9d239744f9ba6ef0b58059d97d640755e609750 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 22:01:02 -0700 Subject: [PATCH 184/250] docs(sla): address doc-review consensus (cycle 130) Require HIDDEN_IDS before a live fleet re-list, and omit end_date when an SLA edit should not extend rentals. Co-authored-by: Cursor --- host/sla-offers.mdx | 17 ++++++++++++++--- snippets/host/cli/list-machine.mdx | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 180670fe..f8d46e70 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -360,7 +360,7 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - On a **new** ask (first publish, or a new offer after unlist), omitted `price_inetu` and `price_inetd` become `0` (free bandwidth) and omitted `credit_discount_max` becomes `0.4`. Updating an existing ask keeps those values when they are omitted. Send `listed_inet_up_cost`, `listed_inet_down_cost`, and `credit_discount_max` when you create the offer. - Send **either** `duration` (integer seconds; a float such as `2592000.0` returns 400 `Invalid duration`) **or** `end_date`, never both. Sending both returns `400` `Cannot set both duration and end_date`. -Always read the current listing and send `price_disk` plus either `duration` or `end_date`. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. +Always read the current listing and send `price_disk`. To change Claim or Confidence on a rented machine **without** extending rentals, omit both `duration` and `end_date`. The stored end date stays, and no contract is extended. Omitting `duration` on a rolling listing turns auto-renew off. Send `duration` (integer seconds) or `end_date` only when you mean to keep auto-renew or to extend. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. Read current listing fields from `vastai show machines --raw`: @@ -377,6 +377,12 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge ### Fleet SLA re-list (machines that already have an SLA) +Use this loop only to restore SLA offers that no longer appear in search on machines with **zero** rentals. It does not change prices or SLA terms. To change terms, use [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). + + +"Missing from search" also matches every **hidden** listing (hidden listings are not shown in search) and every **offline** machine (`create_asks` returns HTTP 402 until the machine is online). Any hidden machine not listed in `HIDDEN_IDS` becomes **public** on a live run. Machines in `HIDDEN_IDS` show up as "would re-list" in every dry run. That is expected. Set `HIDDEN_IDS` before `DRY_RUN=0` (space-separated IDs, or `HIDDEN_IDS=none` if you have no hidden listings). + + **Console hosts:** skip this section. Enable an SLA with [Web console](#web-console) and check settlement in [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). @@ -425,8 +431,13 @@ This example is illustrative: it sleeps between machines and logs success/error # Set DRY_RUN=0 to apply. # ALLOWLIST required for DRY_RUN=0 (space-separated listed machine IDs). ALLOWLIST="${ALLOWLIST:-}" -# Hidden listings: show machines does not return hidden_listing, and omitting it -# makes the listing public. Put every hidden machine ID here, or leave it off ALLOWLIST. +# Hidden listings: show machines does not return hidden_listing. A live PUT +# without hidden_listing: true makes the listing public. Set HIDDEN_IDS to +# every hidden machine ID, or HIDDEN_IDS=none if you have no hidden listings. +if [ "${DRY_RUN:-1}" = "0" ] && { [ -z "${HIDDEN_IDS+x}" ] || [ -z "$HIDDEN_IDS" ]; }; then + echo "abort: set HIDDEN_IDS (space-separated hidden machine IDs, or HIDDEN_IDS=none) before DRY_RUN=0" >&2 + exit 1 +fi HIDDEN_IDS="${HIDDEN_IDS:-}" # Volume offers: 0 = do not create a volume offer (default). It does not delete one you already have. # Set VOL_SIZE="" only if every allowlisted machine should get the server default (half of free disk). diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index ddda8e9b..e5c2b455 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -13,7 +13,7 @@ On an existing listing, omitted GPU price, bandwidth prices, reserved discount, - **Auto-renew is cleared** unless you pass `-l` again. - **Omitting `-v` can create a volume offer** at half the free disk. Pass `-v 0` to skip that. - **`-m` is required.** Omitting it returns HTTP 400 `invalid_args`. -- **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores missing SLA listings. It does not change prices. +- **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores listed SLA offers that are missing from search, on machines with no rentals. It does not change prices. A hidden listing is also missing from search, so set `HIDDEN_IDS` or the live run makes it public. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. From a99f0bfc6dc5fc6ea5d38c281d5dec86bc8a3b93 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 22:10:30 -0700 Subject: [PATCH 185/250] docs(sla): address doc-review consensus (cycle 131) Stop copy-paste SLA updates from resending end_date, and note that the backtester under-counts days that already had SLA rentals. Co-authored-by: Cursor --- host/sla-backtester.mdx | 1 + host/sla-offers.mdx | 19 ++++++++++--------- snippets/host/cli/list-machine.mdx | 7 ++++--- snippets/host/sdk/list-machine.mdx | 8 +++----- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 695bb88a..e495fabb 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -54,6 +54,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). **Simulation limits** - The replay treats all historical compute as one SLA contract, so it overstates fees and credits when few renters chose SLA. The whole machine is replayed as one contract. Live settlement runs per rental contract, so several concurrent SLA renters on a sliced machine can produce more credits on one day than the simulation shows. Pair this output with [SLA and GPU slicing](/host/sla-offers#sla-and-gpu-slicing). +- **Days that already had SLA rentals are under-counted.** Compute earned on SLA contracts is stored separately from `gpu`, `storage`, and bandwidth, and the replay does not add it back. On those days the simulated fees and credits are too low. Run the backtester before you enable SLA, or on a window with no SLA rentals. - For renter-visible pricing (`dph_total`), use **Set Pricing → SLA** in the console or a REST search with a realistic `target_reliability` (the CLI cannot send `target_reliability` today). - How recent versus long-term uptime is weighted is set automatically from the renter target. It is not a host setting; the value used is echoed in `params.beta`. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f8d46e70..556b39fb 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -292,14 +292,16 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons Some omitted fields reset to defaults (for example `price_disk`, `hidden_listing`, and `duration`). Read the warning under [Full listing update](#full-listing-update-existing-ask) before you copy a body. `"vol_size": 0` keeps a new volume offer from being created. It does not delete a volume offer you already have. ```bash +# Change Claim or Confidence only. Omitting end_date and duration does not extend rentals. # "vol_size": 0 keeps volume offers off. Remove it only if this machine should have a volume offer. +# If the listing auto-renews, send integer "duration" instead of omitting it (omitting duration turns auto-renew off). curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_END_DATE_UNIX` with the machine's current `end_date` from `show machines`, as a number with no quotes. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (it defaults to 1 only when offers are created or re-created). Send `duration` as an integer number of seconds if the listing auto-renews (`show machines` returns a float such as `2592000.0`, which the API rejects), otherwise send `end_date`. Never send both. Send `"hidden_listing": true` if the listing is hidden. See the warning below. Do not copy example prices into a first listing. +Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (it defaults to 1 only when offers are created or re-created). Send `"hidden_listing": true` if the listing is hidden. Do not copy example prices into a first listing. Send `end_date` only in the full listing update below, when you mean to extend. Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price. A change that only raises the SLA fee does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). @@ -307,7 +309,7 @@ Any active rental that ends **before** the `end_date` you send is extended to th #### Full listing update (existing ask) -When you also need to refresh GPU price or `end_date` on an already-listed machine: +When you also need to refresh GPU price or move `end_date`. **This example sends `end_date`.** Every shorter active rental is extended to that timestamp. Omit `end_date` if you only want to change price or SLA terms. ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ @@ -330,7 +332,7 @@ Replace `end_date` with the listing's current Unix timestamp from `show machines Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). -SLA fields example (existing listing, same limit as the curl above): +SLA fields example (existing listing, no extension). Same fields as the curl above, without `end_date`: ```json { @@ -340,7 +342,6 @@ SLA fields example (existing listing, same limit as the curl above): "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, - "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.99, "sla_sigma_x": 0.5 } @@ -536,16 +537,16 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid -**SLA-only update (existing ask only)** — send `machine`, the current `price_disk`, `hidden_listing`, and either `duration` (integer seconds) or `end_date`, plus the SLA fields. Some omitted fields reset, as described in the warning above. Do **not** use this body for a first listing. Replace the placeholders with values from `show machines`. +**SLA-only update (existing ask only)** — send `machine`, the current `price_disk`, `hidden_listing`, and the SLA fields. Omit `duration` and `end_date` unless you intend to extend the offer or keep auto-renew. Some omitted fields reset, as described in the warning above. Do **not** use this body for a first listing. Replace the placeholders with values from `show machines`. ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "end_date": CURRENT_END_DATE_UNIX, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' + -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' ``` -Replace `CURRENT_END_DATE_UNIX` and `CURRENT_MIN_CHUNK` with the current values from `show machines`, as numbers with no quotes. A later `end_date` extends live SLA contracts. `min_chunk` defaults to 1 only when offers are created or re-created, not on an update of a live listing. +Replace `CURRENT_MIN_CHUNK` with the current value from `show machines`, as a number with no quotes. This body does not send `end_date`, so it does not extend rentals. `min_chunk` defaults to 1 only when offers are created or re-created, not on an update of a live listing. **Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. @@ -773,7 +774,7 @@ On SLA rentals, compute pay and the SLA fee are released together as SLA earning After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). -For SLA contracts, `sla_earn` is the escrow released to you that day. It is not a per-contract list of service credits. A lower value can be release timing rather than a credit. For a breakdown on one contract, contact support. It matches the backtester's `escrow_to_host_balance` only when that machine's only rental that day was a single SLA contract at the simulated target. Releases are spread over time rather than paid out the same day, so an early or low day can reflect release timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. +For SLA contracts, `sla_earn` is the escrow released to you that day. It is not a per-contract list of service credits. A lower value can be release timing rather than a credit. For a breakdown on one contract, contact support. Do not treat `sla_earn` as the same number as the backtester's `escrow_to_host_balance`. The replay's compute input leaves out earnings from SLA contracts, so the two diverge on days that already had SLA rentals. See [Simulation limits](/host/sla-backtester#simulation-limits). Releases are spread over time rather than paid out the same day, so an early or low day can reflect release timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index e5c2b455..68c8bb26 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -87,10 +87,11 @@ We strongly recommend you test the machine first and only list when ready. Alway ## Examples ```bash -# On a live listing, -e extends active rentals that end sooner (including SLA). -# Reuse the current end date, storage price, and min GPU count when you only want to reprice. +# Reprice without extending rentals. Omitting -e sends no new end date. +# Pass -l again only if this listing auto-renews. Omitting -l clears auto-renew. +vastai list machine -g 3.50 -s -m -v 0 +# Extend the offer end date. -e extends every active rental that ends sooner, including SLA. vastai list machine -g 3.50 -s -m -v 0 -e -# For an auto-renew listing, pass -l again instead of -e. ``` ## Global Options diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 333505f7..ec8b6d5a 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -66,13 +66,11 @@ VastAI.list_machine( ```python from vastai import VastAI -import os client = VastAI(api_key="YOUR_API_KEY") # Replace price_disk and min_chunk with this machine's current values. -# CURRENT_END_DATE_UNIX must be that machine's future end_date. A past value expires the offer. -# vol_size=0 avoids creating a volume offer. -CURRENT_END_DATE_UNIX = int(os.environ["CURRENT_END_DATE_UNIX"]) -result = client.list_machine(id=12345, price_gpu=3.50, price_disk=0.15, min_chunk=1, vol_size=0, end_date=CURRENT_END_DATE_UNIX) +# Reprice without extending rentals. Do not pass end_date unless you mean to extend. +# Pass duration again only if this listing auto-renews. +result = client.list_machine(id=12345, price_gpu=3.50, price_disk=0.15, min_chunk=1, vol_size=0) print(result) ``` From e566f2a2bdf65996798adb2edb46583b3eab8a07 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 22:16:46 -0700 Subject: [PATCH 186/250] docs(sla): address doc-review consensus (cycle 132) Point console renters at Charges, name both maintenance UIs, and mark schedule-maint --sdate as required. Co-authored-by: Cursor --- api-reference/openapi.yaml | 1 - api-reference/openapi/yaml/show_instances.yaml | 1 - guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-offers.mdx | 18 ++++++++++-------- snippets/host/cli/schedule-maint.mdx | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 3a2516b0..dd3fff18 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8096,7 +8096,6 @@ paths: 5, then capped at 25. Prefer an explicit limit. schema: type: integer - default: 5 maximum: 25 example: 25 - name: after_token diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index 53b8c802..56bea14f 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -24,7 +24,6 @@ paths: description: Instances per page. Maximum 25. If omitted, the server starts from 60 and then caps the page at 25. A non-positive limit is treated as 5, then capped at 25. Prefer an explicit limit. schema: type: integer - default: 5 maximum: 25 example: 25 - name: after_token diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 6d9096fa..89d0570b 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability promise on an **on-demand** rental. You pay an hourly **SLA fee** on top of compute, but only after you set a **reliability target** at rent time. The fee is usually small when your target is well below the host's reliability commitment. It can approach the GPU price when your target is close to that commitment. The console shows the fee as the **SLA Fee** line. API fields call it a premium (for example `slaPremiumPerHour`). A **service credit** is paid only when measured reliability falls below your target. In **Account → Billing → Charges**, and in `GET /api/v0/charges/`, that settlement is one net row (SLA fee minus any service credit). The console labels the row **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. A credit smaller than the fee shows up as a smaller **SLA Fee** row, not a separate line. A short outage that stays above the target is billed with no credit. Search can show the price; it does not turn the SLA on by itself. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability commitment on an **on-demand** rental. You set a **Reliability target** before you rent and pay an hourly **SLA fee**. If measured reliability falls below your target, you receive a **service credit**. Searching or filtering by reliability does not turn an SLA on. Set a **Reliability target** and confirm an **SLA Fee** line before you click **RENT**. See [Settlement timing](#settlement-timing) for how fees and credits show up on Charges. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -38,7 +38,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown, then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. -6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing**. +6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. A negative net is labeled **Service Credit**. Any other net is labeled **SLA Fee**. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 556b39fb..54fbb4b3 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -56,6 +56,8 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong If you expect downtime during active rentals, notify renters before you take the machine down. Use either the console ([Set a maintenance window](/host/set-maintenance-window)) or the CLI/REST ([`vastai schedule maint`](/host/cli/schedule-maint)). Use one path per window. For maintenance forgiveness, follow [Scheduled maintenance](#scheduled-maintenance): at least 24 hours' notice. Forgiveness is not guaranteed, and it is not a service credit paid to you. +Hosts cannot currently see which active rentals carry an SLA. If SLA was enabled at any point during a rental that is still active, follow the SLA maintenance path: schedule the window at least 24 hours ahead. See [Scheduled maintenance](#scheduled-maintenance). + **Pre-flight checklist (before tuning reliability commitment and confidence):** - Hosting requires a separate host account and hosting agreement — see [Account setup](/host/hosting-overview#account-setup-and-hosting-agreement) if you have not completed host onboarding. @@ -88,7 +90,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. If it met the renter's target, you keep the SLA fee and no credit is paid. If it fell short, the renter receives a **service credit** from your earnings. A single bad day after a stretch of good uptime can owe less than that day's raw uptime suggests. Raw uptime at or slightly above the target can still owe a partial credit when the blend is below it. +6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. If it met the renter's target, you keep the SLA fee and no credit is paid. If it fell short, the renter receives a **service credit** from your earnings. After a stretch of good uptime, a single bad day can cost you a smaller credit than that day's raw uptime suggests. Even when raw uptime is at or slightly above the target, you can still owe a partial credit if the blended measure is below it. 7. One bad day can cost more than many days of fees. What this is not: @@ -229,7 +231,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. Raising the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. A Claim or Confidence change that only raises the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -304,7 +306,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (it defaults to 1 only when offers are created or re-created). Send `"hidden_listing": true` if the listing is hidden. Do not copy example prices into a first listing. Send `end_date` only in the full listing update below, when you mean to extend. -Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price. A change that only raises the SLA fee does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). +Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price. A Claim or Confidence change that only raises the SLA fee does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). #### Full listing update (existing ask) @@ -645,7 +647,7 @@ Settlement uses a **blended** reliability measure (recent plus longer-term uptim Example: you publish **reliability commitment 99%**, the client chose **target 95%**, and the **blended** measure is **~97%**. - **Credits** are evaluated against the client's **target** (95%), not your reliability commitment. -- Because that blended 97% is above 95%, you **owe no SLA credit** for that day. Raw uptime in the same range can still credit if the blend is below the target. +- Because that blended 97% is above 95%, you **owe no SLA credit** for that day. Even when raw uptime is in the same range, you can still owe a partial credit if the blended measure is below the target. - **SLA fees** are priced from your **reliability commitment**, confidence, and the client's target — a higher reliability commitment relative to the target generally means lower client charges. The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what drives service-credit eligibility. @@ -688,12 +690,12 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi ### Scheduled maintenance -Notify renters in the console ([Set a maintenance window](/host/set-maintenance-window)) or with CLI/REST. After you schedule from the CLI or API, confirm the window under **Host → Machines → Settings → Machine Maintenances**. Do not schedule the same downtime twice. Maintenance-forgiveness review looks for at least 24 hours of notice. Forgiveness is not guaranteed, and it does not pay the host. +Notify renters in the console ([Set a maintenance window](/host/set-maintenance-window)) or with CLI/REST. After you schedule from the CLI or API, confirm the window in the **Machine Maintenances** tab (redesigned Machines page) or the **Scheduled Maintenances** list (classic Machines page). Do not schedule the same downtime twice. Maintenance-forgiveness review looks for at least 24 hours of notice. Forgiveness is not guaranteed, and it does not pay the host. **Console** -1. Open [Host → Machines](https://cloud.vast.ai/host/machines/), then **Settings** → **Machine Maintenances**. +1. Open [Host → Machines](https://cloud.vast.ai/host/machines/), then **Settings**. On the redesigned page open **Machine Maintenances**. On the classic page use **Set Machine Maintenance** and confirm the window under **Scheduled Maintenances**. See [Set a maintenance window](/host/set-maintenance-window). 2. Set a start at least 24 hours ahead and a duration in whole hours. The server rounds a fractional duration **down** (minimum 1 hour), so `2.5` becomes a 2-hour window. Round **up** when sizing an SLA maintenance window. 3. Confirm the window is listed in that table before you take the machine down. @@ -723,7 +725,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ `sdate` is Unix epoch seconds (UTC), at least 24 hours ahead for planned notice. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. Windows Vast scheduled stay in place and are listed as `admin_locked`. To change one window, cancel, then create again every window you still want, at least 24 hours ahead, and confirm under **Settings → Machine Maintenances**. +**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. Windows Vast scheduled stay in place and are listed as `admin_locked`. To change one window, cancel, then create again every window you still want, at least 24 hours ahead, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -762,7 +764,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep ``` `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If it is still empty, use the console notes above. Do not unlist until you have the terms. - 2. **Notify renters.** In the console: **Host → Machines → Settings → Machine Maintenances** (see [Set a maintenance window](/host/set-maintenance-window)). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. + 2. **Notify renters.** In the console, open **Settings** and use **Machine Maintenances** (redesigned page) or **Set Machine Maintenance** (classic page). See [Set a maintenance window](/host/set-maintenance-window). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 0a77ad6a..bbbcd336 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -20,12 +20,12 @@ vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_ca ## Options - - Maintenance start time as Unix epoch seconds (UTC). Example: `1677562671`. The CLI sends this value to the API unchanged (REST `sdate` is also epoch seconds). + + Maintenance start time as Unix epoch seconds (UTC). Required. Omitting it crashes the CLI. Example: `1677562671`. The CLI sends this value to the API unchanged (REST `sdate` is also epoch seconds). - Maintenance duration in whole hours. The server rounds fractional values **down** (minimum 1 hour), so `2.5` is stored as 2 hours. Round **up** when sizing an SLA maintenance window. + Maintenance duration in whole hours. If you omit it, the server stores a 1-hour window. The server rounds fractional values **down** (minimum 1 hour), so `2.5` is stored as 2 hours. Round **up** when sizing an SLA maintenance window. From 50d59f82ad1addc565ccffca5f3a512bd170e863 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 22:24:57 -0700 Subject: [PATCH 187/250] docs(sla): address doc-review consensus (cycle 133) Align rental billing with outage charges, and stop maintenance examples from using a past start time. Co-authored-by: Cursor --- api-reference/openapi/yaml/schedule_maint.yaml | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- guides/reference/billing.mdx | 2 +- guides/reference/faq/billing.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index ebcdc67b..4313a46e 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -133,5 +133,5 @@ x-cli-commands: description: Schedule maintenance for a machine. endpoint: /api/v0/machines/{machine_id}/dnotify method: PUT - example: vastai schedule maint 12345 --sdate 1698674400 --duration 2 + example: vastai schedule maint 12345 --sdate $(date -u -d '2 days 02:00:00' +%s) --duration 2 --maintenance_category software diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 89d0570b..718b3af8 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -316,7 +316,7 @@ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** be When you rent an SLA-backed offer **with a target set**: 1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA fee line or `dph_total`. Host confidence is not shown in the web console and is not a setting you control. -2. **Charges and settlement** — compute and the SLA fee accrue while the contract is active, the same way compute does on any rental (see [Billing](/guides/reference/billing)). Only SLA settlement (service credits) happens once per UTC day. +2. **Charges and settlement** — compute, storage, and the SLA fee accrue while the rental contract is active, **including while the machine is offline**. That is different from a non-SLA rental. Only service credits are settled once per UTC day. See [What you pay during an outage](#what-you-pay-during-an-outage). 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA fee with no credit. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index cfbbd054..e125f5a9 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -19,7 +19,7 @@ We accept credit card payments through Stripe and crypto payments through BitPay Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. **When your balance reaches zero (or below):** - - Your instances are **stopped automatically**. If you rent with an SLA, a stop at zero balance is not guaranteed to end the GPU charge or the SLA fee. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). + - Your instances are **stopped automatically**. If you rent with an SLA, a stop at zero balance is not guaranteed to end the GPU charge or the SLA fee. Top up, or **Destroy** the instance if you need those charges to stop. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. On an SLA rental, storage is not the only charge that can continue: a zero-balance stop is not guaranteed to end the GPU charge or the SLA fee. See the first bullet. - To protect accounts with established usage history, **the system allows a short grace period where your balance may go negative before deletion occurs** -- the length of this buffer is calculated based on your account's average daily spend. Accounts with higher historical spend receive a proportionally larger buffer. diff --git a/guides/reference/faq/billing.mdx b/guides/reference/faq/billing.mdx index 46cd9c67..52ab2970 100644 --- a/guides/reference/faq/billing.mdx +++ b/guides/reference/faq/billing.mdx @@ -11,7 +11,7 @@ description: Questions about billing and credits Once you enter a credit card and an email address and both are verified you can then increase your credit balance using one-time payments with the add credit button. Whenever your credit balance hits zero or below, your instances will be stopped automatically, but not destroyed. -You are still charged storage costs for stopped instances, so it is important to destroy instances when you are done using them. On an SLA rental, a stop (including a stop at zero balance) is not guaranteed to end the GPU charge or the SLA fee. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are still charged storage costs for stopped instances, so it is important to destroy instances when you are done using them. On an SLA rental, a stop (including a stop at zero balance) is not guaranteed to end the GPU charge or the SLA fee. Top up, or destroy the instance if you need those charges to stop. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). Your credit card will be automatically charged periodically to pay off any outstanding negative balance. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index c902b7ae..ea7b04c9 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -251,7 +251,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. +- **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. You cannot see which active rentals carry an SLA. If SLA was on at any point during a rental that is still active, use the SLA path below. - **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance at least 24 hours ahead. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It only stops new rentals, and it removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter Claim and Confidence before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 54fbb4b3..e8908810 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -42,7 +42,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** at `0`, **Save**, then click **LIST**. If you do not see an SLA or Claim section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. -5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios)—GPU billing can continue during outages and SLA credits can exceed many days of SLA fees. +5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. On SLA rentals, compute pay is not in `gpu_earn`. It is released over several days as `sla_earn`. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). 7. Review the SLA fee preview. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. Press **Save** only after you accept the preview. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) first. 8. **Verify the live SLA offer.** The machine has been listed since step 2, so **Save** in step 7 already published the SLA terms. From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index bbbcd336..e44dd942 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -21,7 +21,7 @@ vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_ca ## Options - Maintenance start time as Unix epoch seconds (UTC). Required. Omitting it crashes the CLI. Example: `1677562671`. The CLI sends this value to the API unchanged (REST `sdate` is also epoch seconds). + Maintenance start time as Unix epoch seconds (UTC). Required. Omitting it crashes the CLI. Use a future time, for example `$(date -u -d '2 days 02:00:00' +%s)`. The server does not reject a past start. The CLI sends this value to the API unchanged (REST `sdate` is also epoch seconds). From fe1c8199fc51f88a854807f60b91c5af963aa681 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 22:40:21 -0700 Subject: [PATCH 188/250] docs(sla): address doc-review consensus (cycle 134) Send bandwidth prices on fleet re-list, and tell hosts to keep terms show machines does not return. Co-authored-by: Cursor --- api-reference/openapi.yaml | 19 +++++++++-- api-reference/openapi/yaml/list_machine.yaml | 8 +++++ api-reference/openapi/yaml/sla_backtest.yaml | 4 +-- api-reference/permissions.mdx | 4 +-- cli/reference/show-earnings.mdx | 2 +- host/sla-backtester.mdx | 5 +-- host/sla-offers.mdx | 34 +++++++++++++------- snippets/host/cli/list-machine.mdx | 9 ++++-- 8 files changed, 61 insertions(+), 24 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index dd3fff18..87cd17c1 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4583,6 +4583,18 @@ paths: description: When true, the offer is not shown in search. Defaults to false if omitted, which makes a hidden listing public. `show machines` does not return this flag. + vol_size: + type: integer + minimum: 0 + description: Size in GB of a volume offer to create alongside the + machine offer. Send 0 to avoid creating one. Omitting it creates + a volume offer at about half the free disk. Sending 0 does not + delete an existing volume offer. + vol_price: + type: number + format: float + description: Price per GB-month for the volume offer created when + vol_size is set. credit_discount_max: type: number format: float @@ -9542,7 +9554,7 @@ paths: params: r_claim: 0.99 r_target: 0.99 - beta: 0.5 + beta: 0.46 p: 0.6667 '400': description: Bad Request @@ -9573,8 +9585,9 @@ paths: msg: type: string '401': - description: Unauthorized. `error` is `auth_error` for an unknown or invalid - API key, or a key that lacks `machine_read`. + description: Unauthorized. An unknown or invalid API key returns `error` + `auth_error`. A valid key that lacks `machine_read` returns `success` + false and a `msg`, with no `error` field. '403': description: Forbidden. `error` is `auth_error` when the Authorization header is missing ("This action requires login."), `not_owner` when the machine diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 4bbc15d7..beb771a5 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -69,6 +69,14 @@ paths: hidden_listing: type: boolean description: When true, the offer is not shown in search. Defaults to false if omitted, which makes a hidden listing public. `show machines` does not return this flag. + vol_size: + type: integer + minimum: 0 + description: Size in GB of a volume offer to create alongside the machine offer. Send 0 to avoid creating one. Omitting it creates a volume offer at about half the free disk. Sending 0 does not delete an existing volume offer. + vol_price: + type: number + format: float + description: Price per GB-month for the volume offer created when vol_size is set. credit_discount_max: type: number format: float diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index f4939dc7..ce6c98fa 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -179,7 +179,7 @@ paths: params: r_claim: 0.99 r_target: 0.99 - beta: 0.5 + beta: 0.46 p: 0.6667 '400': description: Bad Request @@ -205,7 +205,7 @@ paths: msg: type: string '401': - description: Unauthorized. `error` is `auth_error` for an unknown or invalid API key, or a key that lacks `machine_read`. + description: Unauthorized. An unknown or invalid API key returns `error` `auth_error`. A valid key that lacks `machine_read` returns `success` false and a `msg`, with no `error` field. '403': description: Forbidden. `error` is `auth_error` when the Authorization header is missing ("This action requires login."), `not_owner` when the machine belongs to someone else, or `sla_disabled` when SLA is off for the platform. content: diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index c5c7a017..9077ad6f 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -130,7 +130,7 @@ curl -G "https://console.vast.ai/api/v0/charges/" \ ``` -Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). A smaller or negative amount than the SLA fee you expected means a credit was applied. The row is missing until that day has settled. +Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). An amount smaller than the SLA fee you expected, or a negative amount, means a credit was applied. The row is missing until that day has settled. @@ -143,7 +143,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do **Host SLA automation keys:** `machine_write` applies to all machines on the account. You cannot scope `create_asks` or maintenance to a subset of machines via API key constraints today. Use dedicated keys with rotation and monitoring for fleet jobs. -**Listing + earnings only** (no search)—prefer this for fleet cron jobs: +**Listing + earnings only** (no search). For cron jobs, split this into a `billing_read` key for monitoring and a `machine_read` + `machine_write` key for listing changes: ```json { diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index 17314756..e71be72a 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -37,7 +37,7 @@ vastai show earnings [OPTIONS] Machine id (optional) (alias: `--machine_id`) -`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). `--start_date` and `--end_date` are convenience options. The CLI parses bare dates such as `2026-07-24` in your machine's local time, so append `T00:00:00Z` for an exact UTC day. For REST-only query params `last_days`, `sday`, and `eday` (for example `last_days=1` polling or exact UTC day index), see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing) or [Show Earnings](/api-reference/billing/show-earnings). +`--raw` is the same JSON as [Show Earnings](/api-reference/billing/show-earnings). Host SLA settlement is `per_machine[].sla_earn` (field `machine_id`, not query param `machid`; not fleet-wide `per_day[].sla_earn`). `--start_date` and `--end_date` are convenience options. The CLI parses bare dates such as `2026-07-24` in the local time zone of the computer running the CLI, not UTC, so append `T00:00:00Z` for an exact UTC day. For REST-only query params `last_days`, `sday`, and `eday` (for example `last_days=1` polling or exact UTC day index), see [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing) or [Show Earnings](/api-reference/billing/show-earnings). ## Examples diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index e495fabb..ba26dd1a 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -168,7 +168,7 @@ A successful response looks like this (one `days` row shown; values are illustra "params": { "r_claim": 0.99, "r_target": 0.99, - "beta": 0.5, + "beta": 0.46, "p": 0.6667 } } @@ -261,7 +261,8 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** | 400 | `invalid_params` | The SLA terms don't combine, for example `r_target` greater than `r_claim` | | 400 | `invalid_range` | `start_date` is after `end_date` | | 400 | `range_too_large` | The window is longer than 366 days | -| 401 | `auth_error` | Unknown API key, or the key lacks `machine_read`. See [Authentication](/api-reference/authentication). | +| 401 | `auth_error` | Unknown or invalid API key. | +| 401 | *(no `error` field)* | The key is valid but lacks `machine_read`. `success` is `false` and `msg` names the missing permission. | | 403 | `auth_error` | No `Authorization` header ("This action requires login.") | | 403 | `not_owner` | The machine belongs to another host | | 403 | `sla_disabled` | SLA is not currently enabled on the platform. Try again later or contact support. | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e8908810..364359f1 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -187,13 +187,13 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r ### Confidence values -**This only changes how SLA fees are priced — it does not change how reliability is measured or what credit you owe when a client's target is missed.** Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. +**This only changes how SLA fees are priced — it does not change how reliability is measured or what credit you owe when a client's target is missed.** **Confidence** is how much renters pay for your SLA. Tighter confidence means a lower SLA fee and less fee income for you. It does not change the credit you owe when you miss the target. The API field is `sla_sigma_x` (σ). Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. -| Console label | API `sla_sigma_x` | Backtester `p` | Pricing effect | -| --- | --- | --- | --- | -| Tight | `0.2` | ~0.83 | Lowest client SLA fees at a given target | -| Normal (default) | `0.5` | ~0.6667 | Balanced | -| Wide | `1.0` | ~0.50 | Highest client SLA fees at a given target | +| Console label | API `sla_sigma_x` (σ) | Backtester `p` | `show machines` | Pricing effect | +| --- | --- | --- | --- | --- | +| Tight | `0.2` (band σ ≤ 0.32) | ~0.83 | `high` | Lowest client SLA fees at a given target | +| Normal (default) | `0.5` (band σ ≤ 0.71) | ~0.6667 | `medium` | Balanced | +| Wide | `1.0` (band σ above 0.71) | ~0.50 | `low` | Highest client SLA fees at a given target | **Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). @@ -204,7 +204,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r Offers with invalid combinations are rejected at listing time: - `sla_r_claim` must be `0` (disable) or greater than 0 and at most **0.99999**. Exactly `1.0` is rejected. -- If you send `sla_sigma_x`, it must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. **Always send `sla_sigma_x` when you enable SLA.** If the claim is above `0` and confidence was never stored, search can quote a **$0** SLA fee while you still carry credit exposure. If a value is already stored, omitting it keeps that value. +- If you send `sla_sigma_x`, it must be positive and at most `3.0`. It defaults to `0.5` only on a new ask. **Always send `sla_sigma_x` when you enable SLA.** If confidence was never stored, SLA fees may not be priced correctly while you still carry credit exposure. If a value is already stored, omitting it keeps that value. - Optional `sla_max_beta` must be in `(0, 1)` and at least the default β derived at your reliability commitment. Hosts do not set β; this field only caps the client-derived β the offer accepts. Omit for uncapped. ```bash @@ -330,7 +330,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ }' ``` -Replace `end_date` with the listing's current Unix timestamp from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e` (parsed in the machine's local time, not UTC). Use a Unix timestamp for an exact UTC end. +Replace `end_date` with the listing's current Unix timestamp from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e` (parsed in the local time zone of the computer running the CLI, not UTC). Use a Unix timestamp for an exact UTC end. Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). @@ -515,6 +515,8 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim, hidden_listing: $hidden} + + (if .listed_inet_up_cost == null then {} else {price_inetu: .listed_inet_up_cost} end) + + (if .listed_inet_down_cost == null then {} else {price_inetd: .listed_inet_down_cost} end) + (if .duration == null then {end_date} else {duration: (.duration | floor)} end) + (if $vol == "" then {} else {vol_size: ($vol|tonumber)} end)') if [ "$DRY_RUN" != "0" ]; then @@ -527,6 +529,9 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do ok=$(echo "$resp" | jq -r '.success // empty') if [ "$ok" = "true" ]; then echo "machine_id=$id ok extended=$(echo "$resp" | jq -c '.results[0].upd_contracts // []')" + if echo "$resp" | jq -e '.results[0].new_contracts | length > 0' >/dev/null; then + echo "WARN machine_id=$id: re-list created a new ask; confirm bandwidth, credit_discount_max, and price_min_bid" >&2 + fi else echo "machine_id=$id error: $(echo "$resp" | jq -c '{success, error: (.error // .results[0].error), msg: (.msg // .results[0].msg)}' 2>/dev/null || echo "$resp")" fi @@ -534,7 +539,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices. It cannot read `credit_discount_max` or `price_min_bid`. If you use non-default values, add them to the body from your own record. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. @@ -751,7 +756,12 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — `sla_earn` is not a per-contract credit record, and the backtester is an estimate, not the settlement. Contact support with the machine ID and the UTC dates. - **Severe outage (active SLA contracts):** - 1. **Save your current terms before you unlist.** After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, and SLA terms. The snapshot does not include confidence (`sla_sigma_x`; only the `sla_confidence` label) or hidden status (`hidden_listing`). Write both down either way. + + + **Keep your own record of listing terms.** `show machines` returns the confidence band (`sla_confidence`), not the exact `sla_sigma_x`, and it does not return `credit_discount_max` or `price_min_bid`. An offline machine drops out of `show machines` after about 10 hours (about 3 days with `include_offline=true`). Write those values down whenever you change them. + + + 1. **Get your current terms.** If the machine is still visible, save them now. If it is not, use the record from the warning above. After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, and SLA terms. The snapshot also omits hidden status (`hidden_listing`). Write that down too. **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, Confidence (Tight, Normal, or Wide), the reserved discount, and the interruptible min bid. An omitted reserved discount on a new ask becomes `0.4`. @@ -768,7 +778,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. If the snapshot lacks the discount or min bid, use the console notes. Relisting creates a new ask, and an omitted `credit_discount_max` becomes `0.4`. Send `sla_sigma_x` explicitly; a new ask otherwise defaults to 0.5. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` never returns `credit_discount_max` or `price_min_bid`, so a snapshot alone is never complete. Restore those, and the exact `sla_sigma_x`, from your own record. Relisting creates a new ask. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing @@ -808,7 +818,7 @@ vastai show earnings --machine_id --start_date "$(date -u -d '7 days ago' + vastai show earnings --machine_id --start_date "$(date -u -v-7d +%F)T00:00:00Z" --end_date "$(date -u +%F)T00:00:00Z" ``` -Keep the `T00:00:00Z` suffix: the CLI parses bare dates such as `2026-07-24` in your machine's local time, so append `T00:00:00Z` for an exact UTC day. On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. +Keep the `T00:00:00Z` suffix: the CLI parses bare dates such as `2026-07-24` in the local time zone of the computer running the CLI, not UTC, so append `T00:00:00Z` for an exact UTC day. On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. **Linux (GNU date) — one UTC day (exact settlement check):** diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 68c8bb26..905c4797 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -5,13 +5,18 @@ Lists a machine for rent. SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. -On an existing listing, omitted GPU price, bandwidth prices, reserved discount, and `end_date` are kept. These are not: +On an existing listing, omitted GPU price, bandwidth prices, reserved discount, and `end_date` are kept. + +**Reset when omitted:** - **Hidden listings become public.** There is no flag for `hidden_listing`. -- **`-e` / `-l` can extend active rentals,** including SLA contracts. Normal CLI output does not print that. Pass `--raw` and read `.results[0].upd_contracts`. - **Storage price resets to $0.10/GB/month** unless you pass `-s`. - **Auto-renew is cleared** unless you pass `-l` again. - **Omitting `-v` can create a volume offer** at half the free disk. Pass `-v 0` to skip that. + +**Other cautions:** + +- **Passing `-e` or `-l` can extend active rentals,** including SLA contracts. Normal CLI output does not print that. Pass `--raw` and read `.results[0].upd_contracts`. - **`-m` is required.** Omitting it returns HTTP 400 `invalid_args`. - **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores listed SLA offers that are missing from search, on machines with no rentals. It does not change prices. A hidden listing is also missing from search, so set `HIDDEN_IDS` or the live run makes it public. From b6fc468ed3fe98bce975c5be42341c6b20d3b7da Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 22:50:42 -0700 Subject: [PATCH 189/250] docs(sla): address doc-review consensus (cycle 135) Carry credit_discount_max on re-list, and stop telling hosts that show machines never returns it. Co-authored-by: Cursor --- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 37 +++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index ba26dd1a..485f60c3 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -280,7 +280,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** ## Fleet workflow -Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. +Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. For machines that already have SLA enabled, the replay under-counts those days. Treat `net_sla` and `largest_day_credit` as a lower bound, or set the window to dates from before SLA was enabled. See [Simulation limits](#simulation-limits). **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 364359f1..3fe76487 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -44,11 +44,10 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. On SLA rentals, compute pay is not in `gpu_earn`. It is released over several days as `sla_earn`. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). -7. Review the SLA fee preview. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. Press **Save** only after you accept the preview. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) first. -8. **Verify the live SLA offer.** The machine has been listed since step 2, so **Save** in step 7 already published the SLA terms. From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. +7. **Save.** The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. +8. **Verify now.** From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). -9. With the client account from step 2, rent your own offer with a **Reliability target** and confirm the SLA Fee line (billed like any rental). See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). ## Before you enable SLA @@ -86,7 +85,7 @@ On outage days you may still bill clients for **intended** compute **and** owe s SLA is an optional reliability promise on **on-demand** rentals. You do not have to offer it. 1. **You (the host)** state a **reliability commitment**: how often you expect the machine to be up. The API field is `sla_r_claim`. The console may still label this **Claim**. -2. You also set **confidence**: how sure you are of that commitment. This is a spread, not odds. Tighter confidence makes the renter's SLA fee smaller. +2. You also set **confidence**: how wide the SLA fee is around your commitment. **Tight** means a smaller fee. See [Confidence values](#confidence-values). 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. @@ -108,7 +107,7 @@ The field names for the reliability commitment (`sla_r_claim`), confidence, and In **Host → Machines → Set Pricing → SLA** you set host knobs only: - **Reliability commitment** — how often you expect the machine to be up (shown to clients as `expected_reliability`; API field `sla_r_claim`; the console may still label this Claim). -- **Confidence** — how tightly you price around that commitment (`sla_sigma_x`; lower = tighter / cheaper for clients at a given reliability target). This is not odds. +- **Confidence** — how wide the SLA fee is around your commitment (`sla_sigma_x`; lower = tighter and a smaller fee). See [Confidence values](#confidence-values). Clients choose their own **reliability target** at search and rent time. You do **not** set the client target on the listing. @@ -116,7 +115,7 @@ Clients choose their own **reliability target** at search and rent time. You do Think of an SLA offer as two host ideas plus one client choice: 1. **Your reliability commitment** — what you believe your machine will deliver (`sla_r_claim`). Setting this above `0` enables SLA on the offer. -2. **Your confidence** — how wide your belief is around that reliability commitment (`sla_sigma_x`). Tighter confidence → lower SLA fees for clients at a given target; wider confidence → higher charges. +2. **Your confidence** — how wide the SLA fee is around that commitment. **Tight** means a smaller fee. See [Confidence values](#confidence-values). 3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA fee sizing use this target. A renter's target must be **at or below** your reliability commitment. Search hides offers whose commitment is below the target, and rent rejects that combination. When a client rents an on-demand instance on your SLA-listed offer with a chosen target: @@ -187,7 +186,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r ### Confidence values -**This only changes how SLA fees are priced — it does not change how reliability is measured or what credit you owe when a client's target is missed.** **Confidence** is how much renters pay for your SLA. Tighter confidence means a lower SLA fee and less fee income for you. It does not change the credit you owe when you miss the target. The API field is `sla_sigma_x` (σ). Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. +**Confidence** sets how wide a pricing margin is built into the SLA fee around your reliability commitment. **Tight** means a smaller fee and less fee income for you. **Wide** means a larger fee. Confidence never changes the credit you owe when a renter's target is missed. The API field is `sla_sigma_x` (σ): a lower value is tighter. Backtester `p` runs the other way: a higher value is tighter. `show machines` uses `high`, `medium`, and `low` (`low` is Wide). Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. | Console label | API `sla_sigma_x` (σ) | Backtester `p` | `show machines` | Pricing effect | | --- | --- | --- | --- | --- | @@ -296,7 +295,8 @@ Some omitted fields reset to defaults (for example `price_disk`, `hidden_listing ```bash # Change Claim or Confidence only. Omitting end_date and duration does not extend rentals. # "vol_size": 0 keeps volume offers off. Remove it only if this machine should have a volume offer. -# If the listing auto-renews, send integer "duration" instead of omitting it (omitting duration turns auto-renew off). +# Rolling listings: omit duration to turn auto-renew off without extending rentals. +# Sending integer duration keeps auto-renew on and extends every shorter rental. curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ @@ -356,7 +356,7 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - `price_gpu` is kept if omitted. - `price_disk` resets to **$0.10/GB/month** if omitted or `null`. -- `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing). While `duration` is set, the offer end date moves forward on its own, and active SLA rentals are extended with it. Credit exposure continues for as long as that listing stays live. +- `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing, and nothing is extended). Sending integer `duration` keeps auto-renew on and extends every shorter rental, including SLA rentals. There is no way to change Claim or Confidence on a rolling listing while keeping auto-renew on and not extending rentals. - `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. - `min_chunk` defaults to **1** when offers are created or re-created (first publish, or relisting after an unlist). On an already-listed machine, omitting it does not change the current minimum. Still send `listed_min_gpu_count` so a later relist does not slice the machine by accident. - `vol_size` omitted on a machine with no volume offer creates one sized at half the free disk. Send `"vol_size": 0` to keep that from happening. `0` does not delete a volume offer that already exists. @@ -486,8 +486,8 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: SLA enabled but no stored confidence; set sla_sigma_x first" >&2 continue fi - # current_rentals_running ignores stopped instances. extend_cur_conts still - # extends every shorter contract, so gate on resident count (includes stopped). + # current_rentals_running ignores stopped instances. A PUT that resends end_date + # extends every shorter contract, including stopped ones, so gate on resident count. if ! echo "$machine" | jq -e 'has("current_rentals_resident") and .current_rentals_resident == 0' >/dev/null; then echo "skip $id: has rentals (including stopped) or current_rentals_resident missing" >&2 continue @@ -517,6 +517,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do hidden_listing: $hidden} + (if .listed_inet_up_cost == null then {} else {price_inetu: .listed_inet_up_cost} end) + (if .listed_inet_down_cost == null then {} else {price_inetd: .listed_inet_down_cost} end) + + (if .credit_discount_max == null then {} else {credit_discount_max: .credit_discount_max} end) + (if .duration == null then {end_date} else {duration: (.duration | floor)} end) + (if $vol == "" then {} else {vol_size: ($vol|tonumber)} end)') if [ "$DRY_RUN" != "0" ]; then @@ -539,7 +540,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices. It cannot read `credit_discount_max` or `price_min_bid`. If you use non-default values, add them to the body from your own record. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). It also returns `min_bid_price`, which already includes the platform fee. Do not copy that into `price_min_bid`. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. @@ -758,10 +759,11 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep - **Severe outage (active SLA contracts):** - **Keep your own record of listing terms.** `show machines` returns the confidence band (`sla_confidence`), not the exact `sla_sigma_x`, and it does not return `credit_discount_max` or `price_min_bid`. An offline machine drops out of `show machines` after about 10 hours (about 3 days with `include_offline=true`). Write those values down whenever you change them. + **Keep your own record of the exact `sla_sigma_x`.** `show machines` returns only the confidence band. It does return `credit_discount_max` while the machine is listed (`null` after unlist) and `min_bid_price` (the read-side min bid, including the platform fee). Do not copy `min_bid_price` into `price_min_bid`. An offline machine drops out of `show machines` after about 10 hours (about 3 days with `include_offline=true`). Snapshot before you unlist. - 1. **Get your current terms.** If the machine is still visible, save them now. If it is not, use the record from the warning above. After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, and SLA terms. The snapshot also omits hidden status (`hidden_listing`). Write that down too. + 1. **Notify renters.** In the console, open **Settings** and use **Machine Maintenances** (redesigned page) or **Set Machine Maintenance** (classic page). See [Set a maintenance window](/host/set-maintenance-window). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. + 2. **Get your current terms before you unlist.** If the machine is still visible, save them now. If it is not, use your own notes. After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, `credit_discount_max`, and SLA terms. The snapshot also omits hidden status (`hidden_listing`) and the exact `sla_sigma_x`. Write those down too. **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, Confidence (Tight, Normal, or Wide), the reserved discount, and the interruptible min bid. An omitted reserved discount on a new ask becomes `0.4`. @@ -773,12 +775,11 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep || echo "Snapshot is EMPTY: do not unlist yet" >&2 ``` - `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If it is still empty, use the console notes above. Do not unlist until you have the terms. - 2. **Notify renters.** In the console, open **Settings** and use **Machine Maintenances** (redesigned page) or **Set Machine Maintenance** (classic page). See [Set a maintenance window](/host/set-maintenance-window). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. + `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If it is still empty, use the console notes above. Do not unlist until you have the terms. 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` never returns `credit_discount_max` or `price_min_bid`, so a snapshot alone is never complete. Restore those, and the exact `sla_sigma_x`, from your own record. Relisting creates a new ask. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` returns `credit_discount_max` only while the machine is listed. It never returns the exact `sla_sigma_x`. `min_bid_price` includes the platform fee, so do not copy it into `price_min_bid`. Relisting creates a new ask. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing @@ -786,7 +787,7 @@ On SLA rentals, compute pay and the SLA fee are released together as SLA earning After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). -For SLA contracts, `sla_earn` is the escrow released to you that day. It is not a per-contract list of service credits. A lower value can be release timing rather than a credit. For a breakdown on one contract, contact support. Do not treat `sla_earn` as the same number as the backtester's `escrow_to_host_balance`. The replay's compute input leaves out earnings from SLA contracts, so the two diverge on days that already had SLA rentals. See [Simulation limits](/host/sla-backtester#simulation-limits). Releases are spread over time rather than paid out the same day, so an early or low day can reflect release timing, not a service credit. A credit can also reduce later releases. Compare several days before you assume a credit, or read `days[].escrow_to_client_balance` in the [backtester](/host/sla-backtester). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. +For SLA contracts, `sla_earn` is the escrow released to you that day. It is not a per-contract list of service credits. A lower value can be release timing rather than a credit. For a breakdown on one contract, contact support. Do not treat `sla_earn` as the same number as the backtester's `escrow_to_host_balance`. The replay's compute input leaves out earnings from SLA contracts, so the two diverge on days that already had SLA rentals. See [Simulation limits](/host/sla-backtester#simulation-limits). Releases are spread over time rather than paid out the same day, so an early or low day can reflect release timing, not a service credit. A credit can also reduce later releases. Compare several days of `per_machine[].sla_earn` before you assume a credit. The backtester cannot confirm a past credit: it under-counts days that already had SLA rentals. See [Simulation limits](/host/sla-backtester#simulation-limits). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. From a6884beb887a1b50ceac70cbd4ab995771c17fc6 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 23:00:33 -0700 Subject: [PATCH 190/250] docs(sla): address doc-review consensus (cycle 136) Correct the min-bid read-back, and document that auto-renew keeps extending SLA rentals. Co-authored-by: Cursor --- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 28 +++++++++++++++++------ sdk/python/reference/create-instance.mdx | 21 +++++++++++------ snippets/host/sdk/list-machine.mdx | 29 +++++++++++++++++++----- 5 files changed, 60 insertions(+), 22 deletions(-) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index ea7b04c9..10f399dd 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -107,7 +107,7 @@ On January 20, you decide to raise the price. You unlist the current offer and r On February 1, Client B rents the other 2 GPUs from the new offer. A rental contract is created at \$2.50/GPU/hr with a rental end date of June 30. -You now have two active rental contracts on the same machine at different prices and different rental end dates. Client A's contract stays at \$2.00 through March 31. Client B's contract stays at \$2.50 through June 30. You must keep the machine online and fully functional through June 30 to honor both contracts. The UI shows June 30 as the latest rental end date on this machine. +You now have two active rental contracts on the same machine at different prices and different rental end dates. Client A's contract stays at \$2.00 through March 31 only because the new offer price is higher. Had you relisted at \$2.00 with a June 30 end date, Client A's contract would also have been extended to June 30, including any SLA terms on it. Client B's contract stays at \$2.50 through June 30. You must keep the machine online and fully functional through June 30 to honor both contracts. The UI shows June 30 as the latest rental end date on this machine. ### Min GPU diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 485f60c3..842722e9 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -339,7 +339,7 @@ done Expect about three seconds per machine (`sleep 3` plus request time), so budget a few minutes for 50 machines. The example logs a failure and moves on after one attempt. On HTTP **429**, wait and retry that machine before treating it as failed. Don't run requests in parallel unless you implement backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). -3. Compare `r_eff`, `r_be`, `net_sla`, and `largest_day_credit` across machines. Skip and failure messages go to stderr, so stdout is one JSON object per machine. Save the script as `bt.sh`, pass any fallbacks on the same line, and sort the results: `R=0.99 P=0.6667 ./bt.sh > results.jsonl && jq -s 'sort_by(.net_sla)' results.jsonl`. +3. Compare `r_eff`, `r_be`, `net_sla`, and `largest_day_credit` across machines. Skip and failure messages go to stderr, so stdout is one JSON object per machine. Save the script as `bt.sh`, pass any fallbacks on the same line, and sort the results: `R=0.99 P=0.6667 bash bt.sh > results.jsonl && jq -s 'map(select(.has_data)) | sort_by(.net_sla)' results.jsonl`. Rows with `has_data: false` are left out of that sort. For machines that already have SLA on, the default window under-counts risk. See [Simulation limits](#simulation-limits). 4. Apply matching `sla_r_claim` / `sla_sigma_x` when listing via the API (see [SLA Offers](/host/sla-offers#api-for-automation)). ## When stuck diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 3fe76487..54765555 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -38,13 +38,13 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist -1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. +1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [Auto-renew and SLA](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** at `0`, **Save**, then click **LIST**. If you do not see an SLA or Claim section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. On SLA rentals, compute pay is not in `gpu_earn`. It is released over several days as `sla_earn`. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). -7. **Save.** The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. +7. Enter **Claim** and **Confidence** (start with **Wide** on a new or volatile machine). Use the units the console field shows. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. 8. **Verify now.** From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -228,7 +228,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput ### SLA on extended contracts -On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. +On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. See the warning under [Full listing update](#full-listing-update-existing-ask). When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. A Claim or Confidence change that only raises the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. @@ -334,6 +334,10 @@ Replace `end_date` with the listing's current Unix timestamp from `show machines Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). + +**Auto-renew and SLA.** If the listing uses auto-renew (`duration`, or `vastai list machine -l`), Vast keeps moving the offer end date forward by that duration and extends active rentals created from that offer, including SLA rentals. Credit exposure can stay open for as long as the renter keeps the instance. To cap it, send a fixed `end_date` and omit `duration`, or unlist. Sending a new `end_date` still extends any rental that ends sooner. + + SLA fields example (existing listing, no extension). Same fields as the curl above, without `end_date`: ```json @@ -540,7 +544,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). It also returns `min_bid_price`, which already includes the platform fee. Do not copy that into `price_min_bid`. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). It also returns `min_bid_price`, your host-side minimum bid (net of the platform fee, same idea as `listed_gpu_cost`). The value you read back can differ slightly from what you sent. Resend the `price_min_bid` you wrote down. Omitting it keeps the stored minimum. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. @@ -758,8 +762,18 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep - **Unexpected credit** — `sla_earn` is not a per-contract credit record, and the backtester is an estimate, not the settlement. Contact support with the machine ID and the UTC dates. - **Severe outage (active SLA contracts):** + **Console** + 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). + 2. Write down Claim, Confidence, prices, end date, reserved discount, and min bid from **Set Pricing**. + 3. Unlist the machine. + 4. Fix the problem. + 5. After the next UTC midnight, check **Host → Billing** for that day's SLA earnings. + 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. + + **API** + - **Keep your own record of the exact `sla_sigma_x`.** `show machines` returns only the confidence band. It does return `credit_discount_max` while the machine is listed (`null` after unlist) and `min_bid_price` (the read-side min bid, including the platform fee). Do not copy `min_bid_price` into `price_min_bid`. An offline machine drops out of `show machines` after about 10 hours (about 3 days with `include_offline=true`). Snapshot before you unlist. + **Keep your own record of the exact `sla_sigma_x`.** `show machines` returns only the confidence band. It does return `credit_discount_max` while the machine is listed (`null` after unlist) and `min_bid_price` (your host-side minimum bid, net of the platform fee). The read-back can differ slightly from what you sent, so resend the `price_min_bid` you wrote down. Omitting it keeps the stored minimum. An offline machine drops out of `show machines` after about 10 hours (about 3 days with `include_offline=true`). Snapshot before you unlist. 1. **Notify renters.** In the console, open **Settings** and use **Machine Maintenances** (redesigned page) or **Set Machine Maintenance** (classic page). See [Set a maintenance window](/host/set-maintenance-window). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. @@ -775,11 +789,11 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep || echo "Snapshot is EMPTY: do not unlist yet" >&2 ``` - `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If it is still empty, use the console notes above. Do not unlist until you have the terms. + `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If that `include_offline` response is also empty, use the console notes above. Do not unlist until you have the terms. 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` returns `credit_discount_max` only while the machine is listed. It never returns the exact `sla_sigma_x`. `min_bid_price` includes the platform fee, so do not copy it into `price_min_bid`. Relisting creates a new ask. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` returns `credit_discount_max` only while the machine is listed. It never returns the exact `sla_sigma_x`. `min_bid_price` is your host-side minimum bid, net of the platform fee. It can differ slightly from the `price_min_bid` you sent, so resend the value you wrote down. Omitting `price_min_bid` keeps the stored minimum. Relisting creates a new ask. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 4d3c2ee8..5653a8d4 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -199,13 +199,16 @@ body = { } def instances_for_label(): - found = requests.get( - "https://console.vast.ai/api/v1/instances/", - params={"select_filters": json.dumps({"label": {"eq": label}})}, - headers=headers, - timeout=30, - ) - found.raise_for_status() + try: + found = requests.get( + "https://console.vast.ai/api/v1/instances/", + params={"select_filters": json.dumps({"label": {"eq": label}})}, + headers=headers, + timeout=30, + ) + found.raise_for_status() + except requests.RequestException: + return [] return found.json().get("instances") or [] try: @@ -219,6 +222,10 @@ try: contract_id = response.json().get("new_contract") except requests.HTTPError as exc: status = exc.response.status_code if exc.response is not None else 0 + if status in (400, 404, 410): + raise RuntimeError( + "Offer is gone or cannot start. Re-search and retry with a new offer id and a new label. Do not retry this offer id." + ) if status != 429 and 400 <= status < 500: raise contract_id = None diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index ec8b6d5a..c84300d7 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -17,10 +17,11 @@ VastAI.list_machine( price_inetd: Optional[float] = None, discount_rate: Optional[float] = None, min_chunk: Optional[int] = None, - end_date: Optional[Union[str, int, float]] = None, - duration: Optional[str] = None, - vol_size: Optional[int] = None, - vol_price: Optional[float] = None, + price_min_bid: Optional[float] = None, + end_date: Optional[Union[str, int, float]] = None, + duration: Optional[Union[str, int]] = None, + vol_size: Optional[int] = None, + vol_price: Optional[float] = None, ) -> str ``` @@ -54,8 +55,24 @@ VastAI.list_machine( Minimum GPUs that must be rented together (GPU slicing). - - Offer expiration (Unix timestamp or MM/DD/YYYY). + + Per-GPU minimum bid (host-side). The value you read back as `min_bid_price` can differ slightly from what you sent. + + + + Offer expiration (Unix timestamp or MM/DD/YYYY). Do not pass together with `duration`. Sending it extends shorter active rentals. + + + + Auto-renew window (seconds, or a string such as `"30 days"`). Pass it on every call to keep auto-renew. Omitting it turns auto-renew off. Do not pass together with `end_date`. While it is set, Vast keeps moving the offer end date forward and extends active rentals created from that offer. + + + + Volume offer size in GB. Omitting it can create a volume offer at half the free disk. Pass `0` to skip that. `0` does not delete a volume offer you already have. + + + + Price for the volume offer, if one is created. ## Returns From b7bb681e18f67171af6888992954f807156de77e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 23:08:16 -0700 Subject: [PATCH 191/250] docs(sla): address doc-review consensus (cycle 137) Stop treating every rent HTTP 400 as a missing offer, and drop the undefined extension-job wording. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 2 +- guides/reference/billing.mdx | 4 ++-- host/sla-offers.mdx | 10 ++++----- sdk/python/reference/create-instance.mdx | 25 +++++++++++++++++----- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 718b3af8..6a9f8ce3 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -323,7 +323,7 @@ When you rent an SLA-backed offer **with a target set**: ### What you pay during an outage -Billing continues during downtime. You are still charged for **compute, storage, and the SLA fee** while the contract exists and the instance is unavailable. Leaving a broken instance running continues those charges until you destroy it. +Billing continues during downtime. You are still charged for **compute, storage, and the SLA fee** while the contract exists and the instance is unavailable. Leaving a broken instance running continues those charges until you destroy it. If the host scheduled the downtime as maintenance, forgiven time does not earn a service credit (see [How reliability is measured](#how-reliability-is-measured)). diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index e125f5a9..ece71dbc 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -20,8 +20,8 @@ Once your credits reach \$0.00, your instances, storage volumes, and data **will **When your balance reaches zero (or below):** - Your instances are **stopped automatically**. If you rent with an SLA, a stop at zero balance is not guaranteed to end the GPU charge or the SLA fee. Top up, or **Destroy** the instance if you need those charges to stop. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. - - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. On an SLA rental, storage is not the only charge that can continue: a zero-balance stop is not guaranteed to end the GPU charge or the SLA fee. See the first bullet. + - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. On an SLA rental, GPU and SLA fee charges may still continue while it is stopped (see the first bullet). If you have an SLA rental and no saved card, top up or **Destroy** the instance right away. Destroy deletes the disk. + - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. - To protect accounts with established usage history, **the system allows a short grace period where your balance may go negative before deletion occurs** -- the length of this buffer is calculated based on your account's average daily spend. Accounts with higher historical spend receive a proportionally larger buffer. **What happens next depends on whether you have a payment method on file:** diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 54765555..dc60a546 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -85,7 +85,7 @@ On outage days you may still bill clients for **intended** compute **and** owe s SLA is an optional reliability promise on **on-demand** rentals. You do not have to offer it. 1. **You (the host)** state a **reliability commitment**: how often you expect the machine to be up. The API field is `sla_r_claim`. The console may still label this **Claim**. -2. You also set **confidence**: how wide the SLA fee is around your commitment. **Tight** means a smaller fee. See [Confidence values](#confidence-values). +2. You also set **Confidence**: how much pricing margin is built into the SLA fee around your commitment. **Tight** means a smaller fee. **Wide** means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. @@ -107,7 +107,7 @@ The field names for the reliability commitment (`sla_r_claim`), confidence, and In **Host → Machines → Set Pricing → SLA** you set host knobs only: - **Reliability commitment** — how often you expect the machine to be up (shown to clients as `expected_reliability`; API field `sla_r_claim`; the console may still label this Claim). -- **Confidence** — how wide the SLA fee is around your commitment (`sla_sigma_x`; lower = tighter and a smaller fee). See [Confidence values](#confidence-values). +- **Confidence** — how much pricing margin is built into the SLA fee around your commitment. **Tight** means a smaller fee. **Wide** means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). Clients choose their own **reliability target** at search and rent time. You do **not** set the client target on the listing. @@ -115,7 +115,7 @@ Clients choose their own **reliability target** at search and rent time. You do Think of an SLA offer as two host ideas plus one client choice: 1. **Your reliability commitment** — what you believe your machine will deliver (`sla_r_claim`). Setting this above `0` enables SLA on the offer. -2. **Your confidence** — how wide the SLA fee is around that commitment. **Tight** means a smaller fee. See [Confidence values](#confidence-values). +2. **Your confidence** — how much pricing margin is built into the SLA fee around that commitment. **Tight** means a smaller fee. **Wide** means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). 3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA fee sizing use this target. A renter's target must be **at or below** your reliability commitment. Search hides offers whose commitment is below the target, and rent rejects that combination. When a client rents an on-demand instance on your SLA-listed offer with a chosen target: @@ -230,7 +230,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. See the warning under [Full listing update](#full-listing-update-existing-ask). -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks both the immediate extension and that later one. A Claim or Confidence change that only raises the SLA fee skips only the immediate extension; the later job can still extend the contract under its original SLA terms. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks extension. A Claim or Confidence change alone does not. Assume any shorter active rental may still be extended under its original SLA terms, even if it does not appear in `upd_contracts`. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -768,7 +768,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist the machine. 4. Fix the problem. 5. After the next UTC midnight, check **Host → Billing** for that day's SLA earnings. - 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. + 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. Re-entering an end date later than a rental's current end extends that rental, including SLA rentals from this outage. You cannot see each rental's end date. To avoid extending them, wait until those rentals end before you relist. **API** diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 5653a8d4..b3805100 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -221,13 +221,28 @@ try: response.raise_for_status() contract_id = response.json().get("new_contract") except requests.HTTPError as exc: - status = exc.response.status_code if exc.response is not None else 0 - if status in (400, 404, 410): + resp = exc.response + status = resp.status_code if resp is not None else 0 + try: + body = resp.json() if resp is not None else {} + except ValueError: + body = {} + err = body.get("error", "") if isinstance(body, dict) else "" + msg = body.get("msg", "") if isinstance(body, dict) else "" + offer_gone = ( + status in (404, 410) + or err == "no_such_ask" + or err == "invalid_price" + or (err == "invalid_args" and "404/3603" in str(msg)) + ) + if offer_gone: raise RuntimeError( - "Offer is gone or cannot start. Re-search and retry with a new offer id and a new label. Do not retry this offer id." - ) + "Offer is gone or its price changed. Re-search and retry with a new offer id and a new label. Do not retry this offer id." + ) from exc if status != 429 and 400 <= status < 500: - raise + raise RuntimeError( + f"Rent failed ({status} {err}): {msg}. Fix the request or account. Do not retry this offer id." + ) from exc contract_id = None except (requests.Timeout, requests.ConnectionError): contract_id = None From e6199a2f47e955f60e7a73bab503dba3ec208d0e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 23:36:35 -0700 Subject: [PATCH 192/250] docs(sla): address doc-review consensus (cycle 138) A Claim or Confidence change in the same request can block extension, and on-demand SLA rents send cancel_unavail. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 6 ++++-- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 16 +++++++++------- sdk/python/reference/create-instance.mdx | 2 ++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 6a9f8ce3..a2debd18 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -242,11 +242,12 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", "disk": 50, "target_reliability": 0.95, + "cancel_unavail": true, "label": "rent-YOUR-UUID" }' ``` -On-demand REST rent with default `cancel_unavail` may return **HTTP 410** if the offer cannot start immediately. Re-search and pick a new offer—do not backoff-retry the same id (see the error table below). Use a new `label` on each attempt. +On-demand rent defaults `target_state` to `running`, and then `cancel_unavail` defaults to true when you do not send a bid. Send `"cancel_unavail": true` anyway. With it, an offer that cannot start returns **HTTP 410** instead of a stopped instance. Re-search and pick a new offer. Do not retry the same id (see the error table below). Use a new `label` on each attempt. See [Create Instance](/api-reference/instances/create-instance) and [Search Offers](/api-reference/search/search-offers). @@ -260,6 +261,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ "template_hash_id": "YOUR_TEMPLATE_HASH", "disk": 50, "target_reliability": 0.95, + "cancel_unavail": true, "label": "rent-YOUR-UUID" }' ``` @@ -399,7 +401,7 @@ Console users: open **Instances** → select your instance → **price details**
API integrators: field names and filters -**Rent body (SLA):** Among SLA-related fields, send only `target_reliability`. Host listing fields (`sla_r_claim`, `sla_r_target`) are read-only on the contract. Still send `image` or `template_hash_id` and matching `disk`. +**Rent body (SLA):** Among SLA-related fields, send only `target_reliability`. The host's reliability commitment is `sla_r_claim`, locked on the contract. Your locked target is `target_reliability` (stored as `sla_r_target`). Do not send either `sla_r_*` field when you rent. Still send `image` or `template_hash_id` and matching `disk`. Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 10f399dd..11c4a08a 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -195,7 +195,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. For SLA rentals, an extension also extends service-credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. Lowering Claim or widening Confidence in that same request also skips any SLA contract whose fee would rise. A later request can still extend it. For SLA rentals, an extension also extends service-credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). ## Testing your own machine diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index dc60a546..3a99f24d 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -230,7 +230,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. See the warning under [Full listing update](#full-listing-update-existing-ask). -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks extension. A Claim or Confidence change alone does not. Assume any shorter active rental may still be extended under its original SLA terms, even if it does not appear in `upd_contracts`. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks extension. A Claim or Confidence change in the same request also blocks extension for any contract whose SLA fee would rise. That contract keeps its current end date and is missing from `upd_contracts`. Those changes never alter existing contract terms, and they do not block an extension in a later request. You cannot see each contract's end date. **Host → Machines** shows the latest rental end date on the machine. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -306,7 +306,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (it defaults to 1 only when offers are created or re-created). Send `"hidden_listing": true` if the listing is hidden. Do not copy example prices into a first listing. Send `end_date` only in the full listing update below, when you mean to extend. -Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price. A Claim or Confidence change that only raises the SLA fee does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). +Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes Claim or Confidence in a way that would raise that contract's SLA fee. A Claim or Confidence change does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). #### Full listing update (existing ask) @@ -768,7 +768,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist the machine. 4. Fix the problem. 5. After the next UTC midnight, check **Host → Billing** for that day's SLA earnings. - 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. Re-entering an end date later than a rental's current end extends that rental, including SLA rentals from this outage. You cannot see each rental's end date. To avoid extending them, wait until those rentals end before you relist. + 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. Re-entering an end date later than a rental's current end extends that rental, including SLA rentals from this outage. You cannot see each rental's end date. **Host → Machines** shows the latest rental end date on the machine. Relist after that date so you do not extend any rental. **API** @@ -797,13 +797,15 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep ## Monitoring SLA after listing -On SLA rentals, compute pay and the SLA fee are released together as SLA earnings over several days. A single smaller release can reflect release timing, not a service credit. By itself it is not proof of a credit. - After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). -For SLA contracts, `sla_earn` is the escrow released to you that day. It is not a per-contract list of service credits. A lower value can be release timing rather than a credit. For a breakdown on one contract, contact support. Do not treat `sla_earn` as the same number as the backtester's `escrow_to_host_balance`. The replay's compute input leaves out earnings from SLA contracts, so the two diverge on days that already had SLA rentals. See [Simulation limits](/host/sla-backtester#simulation-limits). Releases are spread over time rather than paid out the same day, so an early or low day can reflect release timing, not a service credit. A credit can also reduce later releases. Compare several days of `per_machine[].sla_earn` before you assume a credit. The backtester cannot confirm a past credit: it under-counts days that already had SLA rentals. See [Simulation limits](/host/sla-backtester#simulation-limits). SLA-contract compute is **not** included in `gpu_earn`, `sto_earn`, or bandwidth earnings, so those fields stay near zero for SLA rentals. `sla_earn` is normally positive and is negative only when a prior day is corrected. Do not compare it to the backtester's largest single-day credit. +**Reading `sla_earn`** -When you poll the API, use **`per_machine[].sla_earn`** for a single machine. **`per_day[].sla_earn` is always fleet-wide**—even if you pass `machid`. +- `sla_earn` is the SLA escrow released to you that day. It is not a list of service credits, and it is not the same number as the backtester's `escrow_to_host_balance`. +- Releases are spread across days, so one low day can be release timing. Compare several days of `per_machine[].sla_earn` with a normal week before you assume a credit. For one contract, contact support. +- The backtester under-counts days that already had SLA rentals, so it cannot confirm a past credit. See [Simulation limits](/host/sla-backtester#simulation-limits). +- SLA-contract compute is not included in `gpu_earn`, `sto_earn`, or bandwidth earnings. `sla_earn` is negative only when a prior day is corrected. +- `per_day[].sla_earn` is fleet-wide even when you pass a machine ID. Use `per_machine[].sla_earn` for one machine. ### Console (recommended for day-to-day checks) diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index b3805100..854bb759 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -195,6 +195,7 @@ body = { "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", "disk": 50, "target_reliability": 0.95, + "cancel_unavail": True, "label": label, } @@ -272,6 +273,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ "image": "pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime", "disk": 50, "target_reliability": 0.95, + "cancel_unavail": true, "label": "rent-YOUR-UUID" }' ``` From 553b7a5dcebfe7635db96338fffd873b7968201b Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 23:36:42 -0700 Subject: [PATCH 193/250] docs(sla): drop the duplicate end-date sentence (cycle 138) Keep the latest rental end date pointer once, next to the extension rule. Co-authored-by: Cursor --- host/sla-offers.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 3a99f24d..fdae0cc8 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -230,7 +230,7 @@ For planning, assume a worst-case day costs up to one full day of covered comput On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. See the warning under [Full listing update](#full-listing-update-existing-ask). -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. You cannot see each contract's end date. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks extension. A Claim or Confidence change in the same request also blocks extension for any contract whose SLA fee would rise. That contract keeps its current end date and is missing from `upd_contracts`. Those changes never alter existing contract terms, and they do not block an extension in a later request. You cannot see each contract's end date. **Host → Machines** shows the latest rental end date on the machine. +When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks extension. A Claim or Confidence change in the same request also blocks extension for any contract whose SLA fee would rise. That contract keeps its current end date and is missing from `upd_contracts`. Those changes never alter existing contract terms, and they do not block an extension in a later request. You cannot see each contract's end date. **Host → Machines** shows the latest rental end date on the machine. Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. From b091b147458b96750bf819ab4de52688091de33c Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 23:49:04 -0700 Subject: [PATCH 194/250] docs(sla): address doc-review consensus (cycle 139) State the outage relist trade-off in one place, and note that cancel maint asks for confirmation. Co-authored-by: Cursor --- api-reference/openapi.yaml | 12 ++++++------ api-reference/openapi/yaml/show_machines.yaml | 5 ++--- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 10 ++++++---- host/sla-offers.mdx | 17 ++++------------- snippets/host/cli/schedule-maint.mdx | 2 +- 6 files changed, 20 insertions(+), 28 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 87cd17c1..8ff5edb0 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9069,10 +9069,9 @@ paths: - number - 'null' description: 'Host reliability commitment (`sla_r_claim` - on create_asks). Values above 0 mean SLA - - is enabled. null unless the machine is listed with SLA - terms. + on create_asks). Returned when SLA terms are visible (listed, + approved, daemon recent enough). `0` means SLA was explicitly + turned off. Null when terms are not visible. ' sla_confidence: @@ -9086,8 +9085,9 @@ paths: description: 'Confidence band for the ask''s `sla_sigma_x`: high = Tight (sigma_x <= 0.32), - medium = Normal (<= 0.71), low = Wide. null unless the - machine is listed with SLA terms. + medium = Normal (<= 0.71), low = Wide. Same visibility + as `sla_reliability_claim`: present when terms are visible, + null otherwise. `low` is Wide, not low risk. ' example: diff --git a/api-reference/openapi/yaml/show_machines.yaml b/api-reference/openapi/yaml/show_machines.yaml index 54642d99..90403bc2 100644 --- a/api-reference/openapi/yaml/show_machines.yaml +++ b/api-reference/openapi/yaml/show_machines.yaml @@ -74,15 +74,14 @@ paths: type: number nullable: true description: | - Host reliability commitment (`sla_r_claim` on create_asks). Values above 0 mean SLA - is enabled. null unless the machine is listed with SLA terms. + Host reliability commitment (`sla_r_claim` on create_asks). Returned when SLA terms are visible (listed, approved, daemon recent enough). `0` means SLA was explicitly turned off. Null when terms are not visible. sla_confidence: type: string nullable: true enum: [high, medium, low] description: | Confidence band for the ask's `sla_sigma_x`: high = Tight (sigma_x <= 0.32), - medium = Normal (<= 0.71), low = Wide. null unless the machine is listed with SLA terms. + medium = Normal (<= 0.71), low = Wide. Same visibility as `sla_reliability_claim`: present when terms are visible, null otherwise. `low` is Wide, not low risk. example: machines: - id: "12345" diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 74df3459..0dee6c1f 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -94,7 +94,7 @@ The CLI can find SLA offers (`has_sla`, `expected_reliability`) but cannot price -**Next step for SLA:** Search only quotes SLA pricing. Enable SLA in the web console (**Reliability target** in **Search filters**, then **RENT**) or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. Do not use `vastai create instance` expecting SLA. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). +**Next step for SLA:** Search quotes an SLA price. It does not enable an SLA. Enable SLA in the web console (**Reliability target** in **Search filters**, then **RENT**) or via REST `PUT /api/v0/asks/{id}/` with `target_reliability`. Do not use `vastai create instance` expecting SLA. See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). ```bash # datacenter GPUs with minimum compute capability and TFLOPs diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index a2debd18..dc54a3b0 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -167,7 +167,7 @@ When you set `target_reliability`, search results include: Hover over the price breakdown on an offer card to see GPU, storage, bandwidth, and the SLA fee separately. -When you search with an SLA target, reserved-instance discounts may not apply to the displayed total. Confirm in the console price breakdown. SLA fees are never discounted. +When you search with an SLA target, the quote is the on-demand price. Reserved-instance discounts are not applied, and SLA fees are never discounted. ### Comparing offers @@ -286,7 +286,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. -**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Each Charges row is one contract. Match `source` to `instance-` plus the contract ID from `new_contract` (or `metadata.label` if you set a unique label at rent), then read the `sla` item in `items[]`. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. +**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Each Charges row is one contract. Match `source` to `instance-` plus the contract ID from `new_contract` (or `metadata.label` if you set a unique label at rent), then read the `sla` item in `items[]`. Store the hourly SLA fee when you rent (the **SLA Fee** line, or the first non-zero `instance.slaPremiumPerHour`). It reads `0` while the instance is stopped or offline even though the fee still accrues, so do not re-sample it later. Expected fee for a UTC day is about that rate times the hours the contract was active, including downtime. A `sla` row smaller than that, or negative, means a credit was applied. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. **Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read the same net `type: "sla"` row from **Account → Billing → Charges** or `GET /api/v0/charges/` (see the billing reconciliation paragraph above). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). @@ -340,7 +340,7 @@ If you qualify for compensation, a **service credit** is applied after daily set ### How reliability is measured -Each day, the platform tracks how long your instance was online. Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: +Each day, the platform tracks how long your instance was online. You cannot see that measured reliability, or the blended figure, in the console or the API. The only settlement signal is the net SLA row on **Charges**. Settlement considers **multiple time windows** — from short intervals out to long contract-scale windows — so: - A single bad hour hurts, but does not always trigger the maximum credit. - A pattern of unreliable uptime produces larger credits over time. @@ -360,6 +360,8 @@ Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host re | Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (credit after the SLA fee) | | Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | +These rows assume the shortfall lasts long enough that the blended measure is that low. A single bad day after several good days usually pays less than the row, because the good days are still in the blend. + **How to read “Credit minus SLA fee”:** this column is only the service credit minus the SLA fee. It is not your net versus a non-SLA rental. On an SLA rental, offline time is still billed as GPU compute, storage, and the SLA fee. On a non-SLA rental it is not, so add that billed downtime when you compare the two. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day where the **blended measure** meets your target does not pay a credit. Raw daily uptime can sit at or slightly above the target while the blended measure is still below it. Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. @@ -446,7 +448,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. The Charges API returns the same net. Invoices do not. +**Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. Compare it with **SLA Fee/hr** × the hours the contract was active that UTC day, including downtime. The Charges API returns the same net. Invoices do not. You cannot see the measured reliability for that day in the console or the API. **API integrators:** **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net. `results[].items[]` with `type: "sla"` is the SLA fee minus any service credit. The console labels a negative amount **Service Credit** and any other amount **SLA Fee**. A row below the fee you expected means a credit was applied. The row is omitted until the window's last day has settled. The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index fdae0cc8..232c948a 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -549,16 +549,7 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid -**SLA-only update (existing ask only)** — send `machine`, the current `price_disk`, `hidden_listing`, and the SLA fields. Omit `duration` and `end_date` unless you intend to extend the offer or keep auto-renew. Some omitted fields reset, as described in the warning above. Do **not** use this body for a first listing. Replace the placeholders with values from `show machines`. - -```bash -curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "sla_r_claim": 0.995, "sla_sigma_x": 0.2}' -``` - -Replace `CURRENT_MIN_CHUNK` with the current value from `show machines`, as a number with no quotes. This body does not send `end_date`, so it does not extend rentals. `min_chunk` defaults to 1 only when offers are created or re-created, not on an update of a live listing. +**SLA-only update (existing ask only).** Use the partial body under [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). Omit `duration` and `end_date` unless you intend to extend the offer or keep auto-renew. Do **not** use that body for a first listing. Start new or volatile machines at Wide, not Tight. **Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. @@ -735,7 +726,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ `sdate` is Unix epoch seconds (UTC), at least 24 hours ahead for planned notice. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. Windows Vast scheduled stay in place and are listed as `admin_locked`. To change one window, cancel, then create again every window you still want, at least 24 hours ahead, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). +**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Otherwise a failed cancel plus a new window leaves duplicates. Windows Vast scheduled stay in place and are listed as `admin_locked`. To change one window, cancel, then create again every window you still want, at least 24 hours ahead, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -768,7 +759,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist the machine. 4. Fix the problem. 5. After the next UTC midnight, check **Host → Billing** for that day's SLA earnings. - 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. Re-entering an end date later than a rental's current end extends that rental, including SLA rentals from this outage. You cannot see each rental's end date. **Host → Machines** shows the latest rental end date on the machine. Relist after that date so you do not extend any rental. + 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. **API** @@ -793,7 +784,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` returns `credit_discount_max` only while the machine is listed. It never returns the exact `sla_sigma_x`. `min_bid_price` is your host-side minimum bid, net of the platform fee. It can differ slightly from the `price_min_bid` you sent, so resend the value you wrote down. Omitting `price_min_bid` keeps the stored minimum. Relisting creates a new ask. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` returns `credit_discount_max` only while the machine is listed. It never returns the exact `sla_sigma_x`. `min_bid_price` is your host-side minimum bid, net of the platform fee. It can differ slightly from the `price_min_bid` you sent, so resend the value you wrote down. Omitting `price_min_bid` keeps the stored minimum. Relisting creates a new ask. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. To avoid that, wait until the latest rental end date shown on **Host → Machines** has passed, then relist. If you relist sooner, assume shorter rentals will be extended. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index e44dd942..8f28bbb2 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -64,7 +64,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine. To reschedule, cancel first, then recreate each window you still want (≥24 hours ahead for planned maintenance-forgiveness review). Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine, and it asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID` and confirm the cancel succeeded before you recreate windows. To reschedule, cancel first, then recreate each window you still want (≥24 hours ahead for planned maintenance-forgiveness review). Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. ## Examples From 3b885b7126c2b493a48e5e7127e900498c5868fc Mon Sep 17 00:00:00 2001 From: rfernandez Date: Thu, 8 Oct 2026 23:59:05 -0700 Subject: [PATCH 195/250] docs(sla): address doc-review consensus (cycle 140) Spell out when an end date extends a rental, and document search truncation and the daily row quota. Co-authored-by: Cursor --- api-reference/openapi.yaml | 6 ++++++ api-reference/openapi/yaml/search_offers.yaml | 4 ++++ api-reference/permissions.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 9 +++++---- host/sla-offers.mdx | 19 ++++++++++++------- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 8ff5edb0..dc054a84 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6926,6 +6926,12 @@ paths: items: type: object additionalProperties: true + truncated: + type: boolean + description: 'True when the server cut the result short of `limit`. + Narrow the query instead of assuming you saw every offer. + + ' example: offers: - id: 12345678 diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index b7d2b789..cc5b5d20 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -299,6 +299,10 @@ paths: items: type: object additionalProperties: true + truncated: + type: boolean + description: | + True when the server cut the result short of `limit`. Narrow the query instead of assuming you saw every offer. example: offers: - id: 12345678 diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 9077ad6f..8c0efd74 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -100,7 +100,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do - Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. -- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (v0 `show instances` omits SLA fields). On a running instance, the SLA fee is `instance.slaPremiumPerHour`; before running, use `search.slaPremiumPerHour`. +- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (v0 `show instances` omits SLA fields). Store `search.slaPremiumPerHour` from that row when the rent succeeds. `instance.slaPremiumPerHour` is a cross-check only while the instance is running. It reads `0` while loading, stopped, or offline. - **Charges:** add `billing_read` only if you read `sla` fee rows on `GET /api/v0/charges/`. The minimum key above cannot call Charges. ```json diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index dc54a3b0..990cfc48 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -34,7 +34,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) has credit or a payment method, add an SSH key under **Account → Keys** (or plan to use a Jupyter/notebook template that does not require SSH; see [Keys](/guides/reference/keys)), and pick a [template](/guides/instances/choosing/templates) in Search (see [Finding & Renting](/guides/instances/choosing/find-and-rent)). 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. -2. In **Search filters** (left bar), set **Reliability target**. +2. In **Search filters** (left bar), set **Reliability target**. If that control is missing, SLA is not available in the console right now. Rent without it, or contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai. 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown, then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. @@ -230,7 +230,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -The CLI default query sends `external=false rentable=true verified=true rented=false` (the `--help` text omits `rented`; see [search offers](/cli/reference/search-offers)). REST `POST /api/v0/bundles/` does **not** filter on `rented`. The server drops that key and returns a `rented` flag on each offer. Drop rows where `rented` is true if you need to hide GPUs you already rent. The CLI `rented=false` default does that filtering in the client. +The CLI default query sends `external=false rentable=true verified=true rented=false` (the `--help` text omits `rented`; see [search offers](/cli/reference/search-offers)). REST `POST /api/v0/bundles/` does **not** filter on `rented`. The server drops that key and returns a `rented` flag on each offer. Drop rows where `rented` is true if you need to hide GPUs you already rent. The CLI `rented=false` default does that filtering in the client. The response includes `truncated`. When it is `true`, the server cut the result short of `limit`. Narrow the query instead of assuming you saw every offer. **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: @@ -300,6 +300,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | | Too many requests | HTTP 429. Detect throttling by the status code. The body differs by endpoint, so do not parse a `detail` field. Stay at or below about 10 search requests per minute per IP. If a `Retry-After` header is present, honor it. Space rent calls at least 5 seconds apart. A burst can block you for longer than that spacing. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message includes `error 403/3586` ("Hosts can only rent their own machines"). The HTTP status is 400, not 403. A host-only key gets this for every offer that is not on its own machines, including a missing offer. | Switch to a renter account key, then re-search (see [Hosting Overview](/host/hosting-overview) self-test note). | @@ -390,7 +391,7 @@ Production settlement uses the multi-window reliability blend described above, n 1. Open **Instances** and select your running instance. 2. Open **price details** only after the instance is **running**. The **SLA Fee** line is hidden while it is loading, stopped, or offline. That does not mean the SLA is missing. -3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. No SLA Fee line on the Search offer, or on a **running** instance, means that rental has no SLA. +3. If the UI shows your **reliability target**, confirm it matches what you selected at search time. No SLA Fee line on the Search offer, or on a **running** instance, means that rental has no SLA. If Search never showed **Reliability target**, SLA is not available in the console right now. ### API integrators @@ -430,7 +431,7 @@ Host ask field `sla_r_claim` on listings is host-side; on active rentals the loc - **Interruptible (bid) rentals** never include SLA, even on SLA-enabled machines. Use on-demand with a reliability target set. - **Prepaid / reserved-only flows** may reject SLA parameters. Use on-demand rentals for an SLA. - Offers without SLA (`expected_reliability = 0` / `has_sla=false`) are excluded when you filter with `has_sla=true` or set a positive `target_reliability`. -- If SLA parameters on an offer are invalid for your target, search may flag an SLA pricing error instead of showing a charge. +- If SLA pricing fails for an offer, that row has no positive SLA fee (`search.slaPremiumPerHour` in the API) even though you set a target. Treat it as unpriced. Drop it before you sort by price, and do not rent it. ## FAQ diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 232c948a..638027bb 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -44,7 +44,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. On SLA rentals, compute pay is not in `gpu_earn`. It is released over several days as `sla_earn`. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). -7. Enter **Claim** and **Confidence** (start with **Wide** on a new or volatile machine). Use the units the console field shows. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. +7. Enter **Claim** and **Confidence**. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the units the console field shows. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. 8. **Verify now.** From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -224,13 +224,18 @@ The backtester replays **machine-level** daily earnings (total compute across al The backtester simulates **one** SLA contract. On a sliced machine, each concurrently rented SLA contract settles separately, so real single-day credits can be higher than that simulated day. -For planning, assume a worst-case day costs up to one full day of covered compute for **each** SLA contract running on the machine that day, plus any closing settlement on a contract's last active day (see [Simulation limits](/host/sla-backtester#simulation-limits)). Ask support if you want a tighter estimate before listing tight SLA terms on sliced machines. +For planning, assume a bad day can cost up to one full day of covered compute for **each** SLA contract on the machine. Vast does not publish whether the closing settlement on a contract's last day can exceed that. Use the backtester's largest simulated day as a planning figure, not a cap (see [Simulation limits](/host/sla-backtester#simulation-limits)). ### SLA on extended contracts -On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. See the warning under [Full listing update](#full-listing-update-existing-ask). +On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. -When a rental contract is extended (by moving the offer end date forward at the same or lower price), the original SLA parameters remain in effect for the extended period. Changing SLA parameters on the offer does not alter SLA terms on existing contracts — only new rental contracts pick up updated SLA settings. Hosts do not set the SLA fee directly. It changes when you change **Claim** or **Confidence** (a wider Confidence raises the fee at a given target). Any `end_date` you send extends every active rental that ends before that timestamp, SLA rentals included, under their original terms. To avoid extending SLA rentals, unlist. If you do send an `end_date`, assume shorter rentals will be extended, and read `upd_contracts` afterwards. Some contracts are extended a few minutes after the response and do not appear in `upd_contracts`. A GPU, disk, or bandwidth price increase blocks extension. A Claim or Confidence change in the same request also blocks extension for any contract whose SLA fee would rise. That contract keeps its current end date and is missing from `upd_contracts`. Those changes never alter existing contract terms, and they do not block an extension in a later request. You cannot see each contract's end date. **Host → Machines** shows the latest rental end date on the machine. +- **Extends shorter rentals:** a request that sends `end_date` or `duration` at the same or a lower GPU, disk, and bandwidth price. +- **Does not extend that contract when the same request:** raises the GPU, disk, or bandwidth price, or changes Claim or Confidence so that contract's SLA fee would rise. The contract keeps its end date and is missing from `upd_contracts`. +- **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A block applies only to that request. The next request that sends `end_date` can still extend the contract under its original SLA terms. +- **You cannot see each contract's end date.** **Host → Machines** shows the latest rental end date on the machine. + +Changing Claim or Confidence does not change SLA terms already locked on a contract. Only new rentals pick up the new terms. Hosts do not set the SLA fee. It changes when you change Claim or Confidence (wider Confidence raises the fee at a given target). Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -384,7 +389,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge ### Fleet SLA re-list (machines that already have an SLA) -Use this loop only to restore SLA offers that no longer appear in search on machines with **zero** rentals. It does not change prices or SLA terms. To change terms, use [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). +Use this loop only to restore SLA offers that no longer appear in search on machines with **zero** rentals. It does not change prices or SLA terms. To change terms, use [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). `current_rentals_resident`, `credit_discount_max`, and `min_bid_price` are on `GET /api/v0/machines/` but are not all in the Show Machines OpenAPI schema yet. A typed client that drops `current_rentals_resident` will skip every machine. "Missing from search" also matches every **hidden** listing (hidden listings are not shown in search) and every **offline** machine (`create_asks` returns HTTP 402 until the machine is online). Any hidden machine not listed in `HIDDEN_IDS` becomes **public** on a live run. Machines in `HIDDEN_IDS` show up as "would re-list" in every dry run. That is expected. Set `HIDDEN_IDS` before `DRY_RUN=0` (space-separated IDs, or `HIDDEN_IDS=none` if you have no hidden listings). @@ -668,7 +673,7 @@ These scenarios show settlement when the blended measure falls **below** a 95% c To put the asymmetry in perspective: at ~$0.20/day in SLA fees, it takes roughly 210 strong days to accumulate the $42 you could lose on a single day at the target boundary. The SLA fee is a small fraction of daily compute, while credits scale against total daily compute. -Your maximum SLA loss on any single settlement day is bounded by that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). The closing settlement on a contract's last day can add more. +Your SLA loss on a normal settlement day is tied to that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). Vast does not publish whether the closing settlement on a contract's last day can exceed that. Use the backtester's largest simulated day as a planning figure, not a cap. ## Risk scenarios @@ -756,7 +761,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Console** 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). 2. Write down Claim, Confidence, prices, end date, reserved discount, and min bid from **Set Pricing**. - 3. Unlist the machine. + 3. Unlist only if the machine is still online and you need to stop new rentals. If it is offline, `create_asks` returns HTTP 402 until the daemon reconnects, and unlisting drops the SLA ask you would then have to rebuild. 4. Fix the problem. 5. After the next UTC midnight, check **Host → Billing** for that day's SLA earnings. 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. From fb51d3c302bd386aa44f35c56bd2d28ce6f8d996 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 00:15:16 -0700 Subject: [PATCH 196/250] docs(sla): address doc-review consensus (cycle 141) Maintenance notice is not a forgiveness cutoff, and the H100 example fee matches the pricing function. Co-authored-by: Cursor --- api-reference/permissions.mdx | 4 +- guides/instances/choosing/sla-coverage.mdx | 16 ++++---- host/hosting-overview.mdx | 6 +-- host/sla-backtester.mdx | 6 +-- host/sla-offers.mdx | 48 +++++++++++----------- snippets/host/cli/schedule-maint.mdx | 6 +-- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 8c0efd74..afc31a0c 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -100,7 +100,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do - Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. -- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances-v1 --raw` (v0 `show instances` omits SLA fields). Store `search.slaPremiumPerHour` from that row when the rent succeeds. `instance.slaPremiumPerHour` is a cross-check only while the instance is running. It reads `0` while loading, stopped, or offline. +- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances --raw` (that command already calls v1). Store `search.slaPremiumPerHour` from the instance row when the rent succeeds. `instance.slaPremiumPerHour` is a cross-check only while the instance is running. It reads `0` while loading, stopped, or offline. - **Charges:** add `billing_read` only if you read `sla` fee rows on `GET /api/v0/charges/`. The minimum key above cannot call Charges. ```json @@ -245,7 +245,7 @@ Below is the complete mapping of which endpoints each permission category contro SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#renter-sla-scoped-key-recipe). - [Show Instance](/api-reference/instances/show-instance) — v0 path; not for SLA verification (use Show Instances v1 / `show instances-v1` as in the renter recipe). -- [Show Instances](/api-reference/instances/show-instances) — this page is `GET /api/v1/instances/`. For SLA fields (`target_reliability`, `instance.slaPremiumPerHour`), use that API or [`vastai show instances-v1 --raw`](/cli/reference/show-instances-v1). Do not use `vastai show instances` for SLA checks. +- [Show Instances](/api-reference/instances/show-instances) — `GET /api/v1/instances/`. For SLA fields (`target_reliability`, `search.slaPremiumPerHour`), use that API. `vastai show instances --raw` calls the same endpoint. - [Show Logs](/api-reference/instances/show-logs) - [Show SSH Keys](/api-reference/instances/show-ssh-keys) - [Show Volumes](/api-reference/volumes/list-volumes) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 990cfc48..fc7971eb 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -108,7 +108,7 @@ Searching with a **reliability target of 95%** on an offer where the host's **re | --- | --- | | GPU compute | $3.50/hr | | Storage (at search allocation) | ~$0.01/hr | -| SLA fee | ~$0.008/hr | +| SLA fee | ~$0.04/hr | | **Total (`dph_total`)** | ~$3.52/hr | ## Finding SLA offers @@ -174,7 +174,7 @@ When you search with an SLA target, the quote is the on-demand price. Reserved-i | Offer | GPU/hr | Host commitment | Your target | SLA fee/hr | | --- | --- | --- | --- | --- | -| A | $3.50 | 99% | 95% | ~$0.008 | +| A | $3.50 | 99% | 95% | ~$0.04 | | B | $3.50 | 95% | 95% | much higher | Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `dph_total` to compare total quoted cost. @@ -286,7 +286,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. -**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Each Charges row is one contract. Match `source` to `instance-` plus the contract ID from `new_contract` (or `metadata.label` if you set a unique label at rent), then read the `sla` item in `items[]`. Store the hourly SLA fee when you rent (the **SLA Fee** line, or the first non-zero `instance.slaPremiumPerHour`). It reads `0` while the instance is stopped or offline even though the fee still accrues, so do not re-sample it later. Expected fee for a UTC day is about that rate times the hours the contract was active, including downtime. A `sla` row smaller than that, or negative, means a credit was applied. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. +**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Each Charges row is one contract. Match `source` to `instance-` plus the contract ID from `new_contract` (or `metadata.label` if you set a unique label at rent), then read the `sla` item in `items[]`. Store the hourly SLA fee when the rent succeeds: `search.slaPremiumPerHour` on the `GET /api/v1/instances/` row for that contract. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. Expected fee for a UTC day is about the stored rate times the hours the contract was active, including downtime. A `sla` row smaller than that, or negative, means a credit was applied. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. **Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read the same net `type: "sla"` row from **Account → Billing → Charges** or `GET /api/v0/charges/` (see the billing reconciliation paragraph above). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). @@ -353,13 +353,13 @@ When a host schedules maintenance in advance, part of that downtime is counted a ### Credit scenarios (simplified) -Using the H100 example ($84/day compute, ~$0.20/day SLA fee, target 95%, host reliability commitment 99%). A day's service credit is capped relative to that UTC day's covered compute (GPU, storage, and bandwidth combined). The dollar figures below use GPU cost only. +Using the H100 example ($84/day compute, ~$0.97/day SLA fee, target 95%, host reliability commitment 99%). A day's service credit is capped relative to that UTC day's covered compute (GPU, storage, and bandwidth combined). The dollar figures below use GPU cost only. | Scenario | Approx. SLA fee | Approx. service credit | Credit minus SLA fee | | --- | --- | --- | --- | -| Above target (excellent / good day) | ~$0.20/day | $0 | **−$0.20** (you paid the SLA fee) | -| Below target (~93–94% for the day) | ~$0.20/day | ~$42 | **+$41.80** (credit after the SLA fee) | -| Severe shortfall (~90% or less) | ~$0.20/day | ~$84 | **+$83.80** | +| Above target (excellent / good day) | ~$0.97/day | $0 | **−$0.97** (you paid the SLA fee) | +| Below target (~93–94% for the day) | ~$0.97/day | ~$42 | **+$41** (credit after the SLA fee) | +| Severe shortfall (~90% or less) | ~$0.97/day | ~$84 | **+$83** | These rows assume the shortfall lasts long enough that the blended measure is that low. A single bad day after several good days usually pays less than the row, because the good days are still in the blend. @@ -398,7 +398,7 @@ Production settlement uses the multi-window reliability blend described above, n Console users: open **Instances** → select your instance → **price details** to confirm the SLA fee and target. Skip the block below if you do not use the API. -**Common mistake:** `vastai show instances` (v0) and `GET /api/v0/instances/{id}/` do not return SLA fields. Verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`. Enabling SLA still requires console or REST — see [Finding SLA offers](#finding-sla-offers). +**Common mistake:** Prefer `GET /api/v1/instances/` for automation. `vastai show instances` already uses that v1 endpoint. Enabling SLA still requires the console or REST — see [Finding SLA offers](#finding-sla-offers).
diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 11c4a08a..73d2b2e5 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. Existing contracts keep their original end dates only when the relist raises the GPU, disk, or bandwidth price. A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. Existing contracts keep their original end dates in some cases, for example when the relist raises a price or changes SLA terms. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. @@ -252,12 +252,12 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. - **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. You cannot see which active rentals carry an SLA. If SLA was on at any point during a rental that is still active, use the SLA path below. -- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance at least 24 hours ahead. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It only stops new rentals, and it removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter Claim and Confidence before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It only stops new rentals, and it removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter Claim and Confidence before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: 1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. -2. **Planned downtime with active renters:** Schedule at least 24 hours ahead from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). +2. **Planned downtime with active renters:** Schedule as far ahead as you can from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). Twenty-four hours is not a forgiveness cutoff. 3. **Emergency or unplanned downtime:** Notify renters immediately, either from the console ([Set a maintenance window](/host/set-maintenance-window)) or with [`vastai schedule maint`](/host/cli/schedule-maint). Use one path per window. For SLA maintenance-forgiveness rules, notice windows, and confirmation steps, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Forgiveness is not guaranteed, and it is not a payment to the host. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 842722e9..825533fb 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -154,7 +154,7 @@ A successful response looks like this (one `days` row shown; values are illustra "start_day": 20567, "end_day": 20657, "r_eff": 0.9987, - "r_be": 0.9712, + "r_be": 0.972, "days": [ { "day": 20567, @@ -167,8 +167,8 @@ A successful response looks like this (one `days` row shown; values are illustra ], "params": { "r_claim": 0.99, - "r_target": 0.99, - "beta": 0.46, + "r_target": 0.95, + "beta": 0.30, "p": 0.6667 } } diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 638027bb..8678eacc 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -39,12 +39,12 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [Auto-renew and SLA](#sla-on-extended-contracts) before you enable SLA. -2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** at `0`, **Save**, then click **LIST**. If you do not see an SLA or Claim section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. +2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** (your reliability commitment, the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA or Claim section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. -5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. On SLA rentals, compute pay is not in `gpu_earn`. It is released over several days as `sla_earn`. -6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on (24-hour notice for planned work). -7. Enter **Claim** and **Confidence**. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the units the console field shows. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. +5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. On SLA rentals, compute pay is not in `gpu_earn`. Much of the escrow can stay held until the contract ends, so a low `sla_earn` over several days is not by itself a credit. +6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. +7. Enter **Claim** and **Confidence**. Enter Claim in the units the console field shows. In the API, 99% is `0.99`, not `99`. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. 8. **Verify now.** From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -52,10 +52,10 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## Before you enable SLA -If you expect downtime during active rentals, notify renters before you take the machine down. Use either the console ([Set a maintenance window](/host/set-maintenance-window)) or the CLI/REST ([`vastai schedule maint`](/host/cli/schedule-maint)). Use one path per window. For maintenance forgiveness, follow [Scheduled maintenance](#scheduled-maintenance): at least 24 hours' notice. Forgiveness is not guaranteed, and it is not a service credit paid to you. +If you expect downtime during active rentals, notify renters before you take the machine down. Use either the console ([Set a maintenance window](/host/set-maintenance-window)) or the CLI/REST ([`vastai schedule maint`](/host/cli/schedule-maint)). Use one path per window. Forgiveness grows with notice and shrinks as the window gets longer. There is no notice that fully forgives the downtime. Forgiveness is not guaranteed, and it is not a service credit paid to you. See [Scheduled maintenance](#scheduled-maintenance). -Hosts cannot currently see which active rentals carry an SLA. If SLA was enabled at any point during a rental that is still active, follow the SLA maintenance path: schedule the window at least 24 hours ahead. See [Scheduled maintenance](#scheduled-maintenance). +Hosts cannot currently see which active rentals carry an SLA. If SLA was enabled at any point during a rental that is still active, follow the SLA maintenance path and schedule as far ahead as you can. See [Scheduled maintenance](#scheduled-maintenance). **Pre-flight checklist (before tuning reliability commitment and confidence):** @@ -133,7 +133,7 @@ SLA reliability is measured at the **rental contract (instance) level** using pl - **Instance fails to start** because the machine is down (driver, disk, network, or daemon) → counts against SLA reliability for that contract. Whether downtime the renter causes (their own Stop or reboot, a bad image, a container crash, or a stop at zero balance) counts against you, or earns them a credit, is not specified. Contact support before you treat that downtime as yours. - **Machine-level outage** while contracts are active → affects settlement for those contracts. -- **Brief host reboots** during active rentals may count as downtime. Vast does not publish a fixed second-level threshold in host docs — treat unplanned reboots as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance) with at least 24 hours' notice when possible. +- **Brief host reboots** during active rentals may count as downtime. Vast does not publish a fixed second-level threshold in host docs — treat unplanned reboots as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance). Notice is not a cutoff that removes the credit. - **Scheduled maintenance** may be partly forgiven (counted as uptime) — see [Scheduled maintenance](#scheduled-maintenance). That is not a service credit. On sliced machines, SLA settles **per rental contract**. If one GPU slice fails but others remain healthy, only contracts on the affected slice are measured for downtime. @@ -231,9 +231,9 @@ For planning, assume a bad day can cost up to one full day of covered compute fo On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. - **Extends shorter rentals:** a request that sends `end_date` or `duration` at the same or a lower GPU, disk, and bandwidth price. -- **Does not extend that contract when the same request:** raises the GPU, disk, or bandwidth price, or changes Claim or Confidence so that contract's SLA fee would rise. The contract keeps its end date and is missing from `upd_contracts`. -- **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A block applies only to that request. The next request that sends `end_date` can still extend the contract under its original SLA terms. -- **You cannot see each contract's end date.** **Host → Machines** shows the latest rental end date on the machine. +- **Skips that contract:** the request raises the GPU, disk, or bandwidth price. For some renters this records a pending price increase, and later extension requests also skip that contract until the renter accepts or declines it. A request that would raise the contract's SLA fee, or that fails an SLA check (for example `sla_r_claim: 0` or a Claim below that contract's target), also skips it. The contract keeps its end date and is missing from `upd_contracts`. +- **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A skip caused only by an SLA-fee change does not stop a later request. A pending price increase does. +- **You cannot see each contract's end date.** **Host → Machines** shows the latest rental end date on the machine. No API field exposes it. Changing Claim or Confidence does not change SLA terms already locked on a contract. Only new rentals pick up the new terms. Hosts do not set the SLA fee. It changes when you change Claim or Confidence (wider Confidence raises the fee at a given target). @@ -549,7 +549,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). It also returns `min_bid_price`, your host-side minimum bid (net of the platform fee, same idea as `listed_gpu_cost`). The value you read back can differ slightly from what you sent. Resend the `price_min_bid` you wrote down. Omitting it keeps the stored minimum. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `show machines` returns `min_bid_price` (your host-side minimum bid, net of the platform fee, same idea as `listed_gpu_cost`). The value you read back can differ slightly from what you sent. Resend the `price_min_bid` you wrote down if you need to change it. On an existing ask, omitting it keeps the stored minimum. After an unlist, resend it: do not rely on the stored value. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. @@ -570,7 +570,7 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid | 400 | `invalid_args` | Machine ID not found for your account, or malformed / incompatible request body | | 400 | `invalid_sla_params` | SLA parameters failed validation | | 429 | *(rate limited)* | Too many requests. Space fleet calls at least 5 seconds apart, then retry the machines that failed | -| 402 | `results[0].msg`: `error: can only create asks for an online machine.` | The daemon has not checked in for more than 60 seconds. Bring the machine online, then retry. If the machine is down, use `vastai unlist machine MACHINE_ID` instead. | +| 402 | `results[0].msg`: `error: can only create asks for an online machine.` | The daemon has not checked in for more than 60 seconds. Bring the machine online, then retry. Do not unlist just because of this error. | **`machine_locked`:** Returned when a machine is decommissioned or migration-locked. If you are migrating hardware, finish or cancel active rentals first, remove or update the listing as needed, and contact support if the machine remains locked. Existing SLA terms on active contracts remain in force until those contracts end. @@ -607,7 +607,7 @@ A non-empty `upd_contracts` means this request extended live rentals. Each contr | Item | Amount | | --- | --- | | Daily compute (`C`) | ~$84/day ($3.50 × 24 hr GPU only — simplified) | -| SLA fee (client pays) | ~**$0.008/hr** (~$0.20/day at 24 hr) | +| SLA fee (client pays) | ~**$0.04/hr** (~$0.97/day at 24 hr) | SLA credits are capped relative to that UTC day's covered compute — GPU, storage, and bandwidth combined — not GPU compute alone. The simplified example below uses GPU-only math for readability; treat the [largest single-day credit](/host/sla-backtester#summarize-with-jq) from the SLA backtester as the authoritative tail-risk figure before you list. @@ -640,7 +640,7 @@ In the **You net** column, values follow host earnings sign conventions: positiv | Blended reliability vs the client's target | You net (per day) | | --- | --- | -| Meets or exceeds the target (for example blended ~99% vs a 95% target) | +$0.20 (keep the full SLA fee) | +| Meets or exceeds the target (for example blended ~99% vs a 95% target) | +$0.97 (keep the full SLA fee) | When the blended measure meets the target, you keep the SLA fee. These rows are not raw uptime. @@ -671,7 +671,7 @@ These scenarios show settlement when the blended measure falls **below** a 95% c | Blended measure ~93–94% (illustrative shortfall) | −$42 (credit you owe) | | Well below target (~90% or less) | −$84 (large credit owed) | -To put the asymmetry in perspective: at ~$0.20/day in SLA fees, it takes roughly 210 strong days to accumulate the $42 you could lose on a single day at the target boundary. The SLA fee is a small fraction of daily compute, while credits scale against total daily compute. +To put the asymmetry in perspective: at about $0.97/day in SLA fees, it takes roughly 44 strong days to accumulate the $42 you could lose on a single day at the target boundary. A full outage day, about $85 of compute plus the fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use Claim 99%, Normal confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. Your SLA loss on a normal settlement day is tied to that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). Vast does not publish whether the closing settlement on a contract's last day can exceed that. Use the backtester's largest simulated day as a planning figure, not a cap. @@ -696,23 +696,23 @@ Clients pay more because you admit greater uncertainty. Use this if your reliabi ### Scheduled maintenance -Notify renters in the console ([Set a maintenance window](/host/set-maintenance-window)) or with CLI/REST. After you schedule from the CLI or API, confirm the window in the **Machine Maintenances** tab (redesigned Machines page) or the **Scheduled Maintenances** list (classic Machines page). Do not schedule the same downtime twice. Maintenance-forgiveness review looks for at least 24 hours of notice. Forgiveness is not guaranteed, and it does not pay the host. +Notify renters in the console ([Set a maintenance window](/host/set-maintenance-window)) or with CLI/REST. After you schedule from the CLI or API, confirm the window in the **Machine Maintenances** tab (redesigned Machines page) or the **Scheduled Maintenances** list (classic Machines page). Do not schedule the same downtime twice. Schedule as far ahead as you can. Forgiveness grows with notice and shrinks as the window gets longer. There is no cutoff at which the downtime is fully forgiven. For a short window, a day of notice forgives only a small share, and a week still leaves a large share unforgiven. Forgiveness is not guaranteed, and it does not pay the host. **Console** 1. Open [Host → Machines](https://cloud.vast.ai/host/machines/), then **Settings**. On the redesigned page open **Machine Maintenances**. On the classic page use **Set Machine Maintenance** and confirm the window under **Scheduled Maintenances**. See [Set a maintenance window](/host/set-maintenance-window). -2. Set a start at least 24 hours ahead and a duration in whole hours. The server rounds a fractional duration **down** (minimum 1 hour), so `2.5` becomes a 2-hour window. Round **up** when sizing an SLA maintenance window. +2. Set the start as far ahead as you can, and set a duration in whole hours. The server rounds a fractional duration **down** (minimum 1 hour), so `2.5` becomes a 2-hour window. Round **up** when sizing an SLA maintenance window. 3. Confirm the window is listed in that table before you take the machine down. **Or use CLI/REST below.** Forgiveness is not guaranteed either way. -**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule at least 24 hours in advance with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. Include `duration` (whole hours) and `maintenance_category`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. +**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). There is no notice cutoff that fully forgives the window. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. Include `duration` (whole hours) and `maintenance_category`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. **`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash -# Planned window ≥24 hours ahead (Linux GNU date). Example: day after tomorrow 02:00 UTC. +# Planned window, as far ahead as you can (Linux GNU date). Example: day after tomorrow 02:00 UTC. # macOS: date -u -j -v+2d -v2H -v0M -v0S +%s vastai schedule maint MACHINE_ID \ --sdate "$(date -u -d '2 days 02:00:00' +%s)" \ @@ -729,9 +729,9 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ -d '{"sdate": START_UNIX_UTC, "duration": 2, "maintenance_category": "software"}' ``` -`sdate` is Unix epoch seconds (UTC), at least 24 hours ahead for planned notice. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). +`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Otherwise a failed cancel plus a new window leaves duplicates. Windows Vast scheduled stay in place and are listed as `admin_locked`. To change one window, cancel, then create again every window you still want, at least 24 hours ahead, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). +**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Otherwise a failed cancel plus a new window leaves duplicates. Windows Vast scheduled stay in place and are listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -786,10 +786,10 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep ``` `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If that `include_offline` response is also empty, use the console notes above. Do not unlist until you have the terms. - 3. **Unlist** in the console (**Host → Machines**). Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline, and resending `end_date` can extend shorter rentals. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. + 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` returns `credit_discount_max` only while the machine is listed. It never returns the exact `sla_sigma_x`. `min_bid_price` is your host-side minimum bid, net of the platform fee. It can differ slightly from the `price_min_bid` you sent, so resend the value you wrote down. Omitting `price_min_bid` keeps the stored minimum. Relisting creates a new ask. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. To avoid that, wait until the latest rental end date shown on **Host → Machines** has passed, then relist. If you relist sooner, assume shorter rentals will be extended. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` returns `credit_discount_max` only while the machine is listed. It never returns the exact `sla_sigma_x`. `min_bid_price` is your host-side minimum bid, net of the platform fee. It can differ slightly from the `price_min_bid` you sent, so resend the value you wrote down. Omitting `price_min_bid` keeps the stored minimum. Relisting creates a new ask. Also send `"vol_size": 0` unless you want a volume offer, and send `duration` as an integer if the listing used auto-renew. Resend `price_min_bid`. Do not rely on a stored minimum after an unlist. No API field shows the latest rental end date. Check **Host → Machines** before you relist. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. To avoid that, wait until the latest rental end date shown on **Host → Machines** has passed, then relist. If you relist sooner, assume shorter rentals will be extended. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing @@ -809,7 +809,7 @@ After you enable SLA, charges and credits settle on UTC (Coordinated Universal T 2. Set the date range to include the UTC day you want to review. 3. Machine filtering is not available in the console. For one machine, use `vastai show earnings --machine_id ID`. 4. Look for the SLA settlement in the earnings breakdown. On an SLA rental, compute pay is released with the SLA fee (the same amount as `sla_earn` in the API), not as a separate GPU earnings line. -5. After downtime, compare several days with a normal week. A single smaller release may only reflect timing, because escrow is released over several days. On its own, it does not prove a credit was paid. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. +5. After downtime, compare several days with a normal week. Much of the escrow can stay held until the contract ends, so a low `sla_earn` is not by itself a credit. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. **If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 8f28bbb2..acc5c205 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -21,7 +21,7 @@ vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_ca ## Options - Maintenance start time as Unix epoch seconds (UTC). Required. Omitting it crashes the CLI. Use a future time, for example `$(date -u -d '2 days 02:00:00' +%s)`. The server does not reject a past start. The CLI sends this value to the API unchanged (REST `sdate` is also epoch seconds). + Maintenance start time as Unix epoch seconds (UTC). Required. Use a future time, as far ahead as you can, for example `$(date -u -d '2 days 02:00:00' +%s)`. The CLI sends this value to the API unchanged (REST `sdate` is also epoch seconds). @@ -44,7 +44,7 @@ The same `schedule maint` command is used for both **planned** and **emergency** ### Planned SLA maintenance -If SLA is enabled and you need planned downtime during an active rental, schedule at least 24 hours in advance. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). +If SLA is enabled and you need planned downtime during an active rental, schedule as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ```bash # Replace MACHINE_ID; --sdate must be a future UTC epoch (≥24h ahead for planned forgiveness review) @@ -64,7 +64,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine, and it asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID` and confirm the cancel succeeded before you recreate windows. To reschedule, cancel first, then recreate each window you still want (≥24 hours ahead for planned maintenance-forgiveness review). Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine, and it asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID` and confirm the cancel succeeded before you recreate windows. To reschedule, cancel first, then recreate each window you still want, as far ahead as you can. Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. ## Examples From 027ea8955880ab144bfcecb4a0df994826af1ef1 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 00:23:49 -0700 Subject: [PATCH 197/250] docs(sla): address doc-review consensus (cycle 142) Match the bad-day fee ratio to the worked example, and stop treating 24 hours as a forgiveness cutoff in the CLI comment. Co-authored-by: Cursor --- api-reference/openapi.yaml | 23 +++++++++++++++++++ api-reference/openapi/yaml/search_offers.yaml | 20 ++++++++++++++++ api-reference/rate-limits-and-errors.mdx | 2 +- cli/rate-limits.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-offers.mdx | 8 +++---- sdk/python/rate-limits.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 3 ++- 8 files changed, 54 insertions(+), 10 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index dc054a84..271b24f3 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -7069,6 +7069,29 @@ paths: msg: type: string example: Invalid user key + '429': + description: 'Too many requests, or the daily search row quota is exhausted. + + `error: search_quota_exceeded` includes a `Retry-After` header (seconds + until the quota resets, which can be hours). + + ' + headers: + Retry-After: + schema: + type: integer + description: Seconds to wait. Present on `search_quota_exceeded`. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: search_quota_exceeded + msg: + type: string + example: Daily search row quota exhausted tags: - Search operationId: searchOffers diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index cc5b5d20..e726fae1 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -439,6 +439,26 @@ paths: msg: type: string example: Invalid user key + '429': + description: | + Too many requests, or the daily search row quota is exhausted. + `error: search_quota_exceeded` includes a `Retry-After` header (seconds until the quota resets, which can be hours). + headers: + Retry-After: + schema: + type: integer + description: Seconds to wait. Present on `search_quota_exceeded`. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: search_quota_exceeded + msg: + type: string + example: Daily search row quota exhausted tags: - Search x-tags: diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index b3d999b3..7ee2d97f 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -44,7 +44,7 @@ or API requests too frequent: endpoint threshold=... ``` -The API does not currently set standard rate-limit headers (for example `Retry-After`), so clients should apply their own backoff strategy. +Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value points at the quota reset, which can be hours away. When `Retry-After` is present, wait at least that long. When it is absent, use your own backoff. ### How to reduce rate limit errors diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 51a6587e..d261ba1c 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -43,7 +43,7 @@ or API requests too frequent: endpoint threshold=... ``` -The API does not return a `Retry-After` header. The CLI handles this automatically using its built-in retry logic. +Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. When it is present, wait at least that long. When it is absent, the CLI uses its own backoff. ## Built-in Retry Behavior diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index fc7971eb..2c8adc7e 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -109,7 +109,7 @@ Searching with a **reliability target of 95%** on an offer where the host's **re | GPU compute | $3.50/hr | | Storage (at search allocation) | ~$0.01/hr | | SLA fee | ~$0.04/hr | -| **Total (`dph_total`)** | ~$3.52/hr | +| **Total (`dph_total`)** | ~$3.55/hr | ## Finding SLA offers @@ -210,7 +210,7 @@ Web app: [cloud.vast.ai](https://cloud.vast.ai). REST examples use `https://cons For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). -**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). +**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. Rows from every query, including shards, count against one daily search row quota that varies by account. Size `limit` and the number of shards to fit that budget. See the **Daily search row quota** row below and [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 8678eacc..f3064036 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -661,7 +661,7 @@ The **reliability commitment** is your belief and pricing knob. The client's **r ### If the client's target is missed -Credits scale relative to the day's compute, not only the SLA fee collected. A single bad day near the client's target boundary can cost as much as 200+ days of collected SLA fees. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. +A single bad day can wipe out weeks or months of SLA fees. In the example below, a day at the client's target boundary costs about 44 days of collected SLA fees, and a full outage day costs about 88 days. Lower renter targets carry lower fees for a similar credit, so the ratio can be higher than this example. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. These scenarios show settlement when the blended measure falls **below** a 95% client target. They are illustrations, not typical strong days: @@ -671,7 +671,7 @@ These scenarios show settlement when the blended measure falls **below** a 95% c | Blended measure ~93–94% (illustrative shortfall) | −$42 (credit you owe) | | Well below target (~90% or less) | −$84 (large credit owed) | -To put the asymmetry in perspective: at about $0.97/day in SLA fees, it takes roughly 44 strong days to accumulate the $42 you could lose on a single day at the target boundary. A full outage day, about $85 of compute plus the fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use Claim 99%, Normal confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. +To put the asymmetry in perspective: at about $0.97/day in SLA fees, it takes roughly 44 strong days to accumulate the $42 you could lose on a single day at the target boundary. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use Claim 99%, Normal confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. Your SLA loss on a normal settlement day is tied to that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). Vast does not publish whether the closing settlement on a contract's last day can exceed that. Use the backtester's largest simulated day as a planning figure, not a cap. @@ -772,7 +772,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Keep your own record of the exact `sla_sigma_x`.** `show machines` returns only the confidence band. It does return `credit_discount_max` while the machine is listed (`null` after unlist) and `min_bid_price` (your host-side minimum bid, net of the platform fee). The read-back can differ slightly from what you sent, so resend the `price_min_bid` you wrote down. Omitting it keeps the stored minimum. An offline machine drops out of `show machines` after about 10 hours (about 3 days with `include_offline=true`). Snapshot before you unlist. - 1. **Notify renters.** In the console, open **Settings** and use **Machine Maintenances** (redesigned page) or **Set Machine Maintenance** (classic page). See [Set a maintenance window](/host/set-maintenance-window). To automate: `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. + 1. **Notify renters.** `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. See [Set a maintenance window](/host/set-maintenance-window). 2. **Get your current terms before you unlist.** If the machine is still visible, save them now. If it is not, use your own notes. After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, `credit_discount_max`, and SLA terms. The snapshot also omits hidden status (`hidden_listing`) and the exact `sla_sigma_x`. Write those down too. **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, Confidence (Tight, Normal, or Wide), the reserved discount, and the interruptible min bid. An omitted reserved discount on a new ask becomes `0.4`. @@ -789,7 +789,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Console:** Open **Set Pricing**, re-enter the prices you wrote down, and confirm **Claim** and **Confidence** match your notes. Click **Save**, then **LIST**. From a client account, search with a **Reliability target** and confirm an **SLA Fee** line. **API:** send the terms you wrote down: GPU price (`price_gpu`), storage (`price_disk`), bandwidth (`price_inetu`, `price_inetd`), min GPU (`min_chunk`), end date or duration, `hidden_listing`, Claim (`sla_r_claim`), Confidence (`sla_sigma_x`), `credit_discount_max`, and `price_min_bid`. `show machines` returns `credit_discount_max` only while the machine is listed. It never returns the exact `sla_sigma_x`. `min_bid_price` is your host-side minimum bid, net of the platform fee. It can differ slightly from the `price_min_bid` you sent, so resend the value you wrote down. Omitting `price_min_bid` keeps the stored minimum. Relisting creates a new ask. Also send `"vol_size": 0` unless you want a volume offer, and send `duration` as an integer if the listing used auto-renew. Resend `price_min_bid`. Do not rely on a stored minimum after an unlist. No API field shows the latest rental end date. Check **Host → Machines** before you relist. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. Resending the old `end_date` extends any shorter active rental. To avoid that, wait until the latest rental end date shown on **Host → Machines** has passed, then relist. If you relist sooner, assume shorter rentals will be extended. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Relist with every field resent.** Relisting after an unlist creates a new ask, so stored values do not carry over. Send all of these in one `create_asks` request, using the values you recorded before unlisting: `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `sla_r_claim`, `sla_sigma_x`, `credit_discount_max`, `price_min_bid`, and `"vol_size": 0` unless you want a volume offer. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. `show machines` never returns the exact `sla_sigma_x`. Sending `end_date` or `duration` extends every active rental that ends sooner. No API field shows the latest rental end date. Check **Host → Machines** before you choose it. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 13c9ad25..8a982c0f 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -45,7 +45,7 @@ or API requests too frequent: endpoint threshold=... ``` -The API does not return a `Retry-After` header. The SDK handles this automatically using its built-in retry logic. +Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. When it is present, wait at least that long. When it is absent, the SDK uses its own backoff. ## Built-in Retry Behavior diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index acc5c205..72c50263 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -47,7 +47,8 @@ The same `schedule maint` command is used for both **planned** and **emergency** If SLA is enabled and you need planned downtime during an active rental, schedule as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ```bash -# Replace MACHINE_ID; --sdate must be a future UTC epoch (≥24h ahead for planned forgiveness review) +# Replace MACHINE_ID; --sdate must be a future UTC epoch. +# Schedule as far ahead as you can (no notice cutoff fully forgives the window). # Linux: date -u -d '2 days 02:00:00' +%s # macOS: date -u -j -v+2d -v2H -v0M -v0S +%s vastai schedule maint MACHINE_ID \ From 1c9a50373f66bb624eb15934dc1fc69aa9add6a1 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 00:34:06 -0700 Subject: [PATCH 198/250] docs(sla): address doc-review consensus (cycle 143) Document the packaged CLI: min GPU defaults to 1, and search does not filter rented offers. Co-authored-by: Cursor --- api-reference/openapi.yaml | 4 ++-- api-reference/openapi/yaml/search_offers.yaml | 2 +- cli/rate-limits.mdx | 8 ++++---- cli/reference/search-offers.mdx | 10 +++++----- guides/instances/choosing/sla-coverage.mdx | 5 +++-- host/sla-offers.mdx | 8 ++++---- sdk/python/rate-limits.mdx | 6 ++++-- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 8 ++++---- 9 files changed, 28 insertions(+), 25 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 271b24f3..cd29ca08 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6661,8 +6661,8 @@ paths: rented: type: object description: 'Not a server-side filter. The server drops this key. - Each offer still includes a `rented` flag. The CLI applies `rented=false` - on the client after the response. + Each offer still includes a `rented` flag. The packaged CLI does + not filter on it either. ' properties: diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index e726fae1..0675b268 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -70,7 +70,7 @@ paths: rented: type: object description: | - Not a server-side filter. The server drops this key. Each offer still includes a `rented` flag. The CLI applies `rented=false` on the client after the response. + Not a server-side filter. The server drops this key. Each offer still includes a `rented` flag. The packaged CLI does not filter on it either. properties: eq: type: boolean diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index d261ba1c..470cca82 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -49,15 +49,15 @@ Some HTTP 429 responses include a `Retry-After` header. The daily search row quo When the CLI receives an HTTP 429 response, it automatically retries the request using exponential backoff: -- **Retried status codes:** 429 only +- **Retried status codes:** 429, 502, 503, and 504, plus connection errors and timeouts - **Default retries:** 3 -- **Backoff strategy:** starts at 0.15 seconds, multiplied by 1.5x after each attempt +- **Backoff strategy:** starts at 0.15 seconds, multiplied by 1.5x after each attempt. The CLI does not read `Retry-After`. - **Retry delays:** ~0.15s, ~0.225s, ~0.34s -For most usage, the defaults handle transient rate limits without any intervention. +For SLA rentals, a timeout or 5xx retry can send the same rent twice. Set a unique label and check instances for that label before you rent again. See [SLA](/guides/instances/choosing/sla-coverage). -The CLI only retries on 429 (rate limit). Other HTTP errors (4xx, 5xx) are reported immediately. +The CLI retries 429, 502, 503, and 504. Other HTTP errors are reported immediately. ## Configuring Retries diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 0dee6c1f..3deeaa70 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -23,7 +23,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] ## Arguments - Query to search for. default: `external=false rentable=true verified=true rented=false` (`--help` omits `rented`). Pass `-n` to ignore the default. + Query to search for. default: `external=false rentable=true verified=true`. Pass `-n` to ignore the default. Neither the CLI nor the server filters on `rented`. ## Options @@ -80,8 +80,8 @@ The CLI can find SLA offers but cannot price them. Treat `dph_total` as SLA-incl ```bash # Marketplace reliability score (not SLA commitment) -# rented=false (excludes slots you already rent) is already in the CLI default query; shown here explicitly -vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090 rented=false' +# neither the CLI nor the server filters on rented; drop .rented == true yourself if you need to +vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090' --raw | jq '[.[] | select(.rented != true)]' # Find SLA offers. dph_total here excludes the SLA fee (see the Warning below). # Always set --storage explicitly when comparing dph_total (CLI default 5 GiB ≠ REST 8 GB). @@ -110,7 +110,7 @@ vastai search offers 'reliability>0.99 gpu_name in [RTX_4090, RTX_3090] geolocat vastai search offers 'disk_space>146 duration>24 gpu_ram>10 cuda_vers>=12.1 direct_port_count>=2 driver_version >= 535.86.05' # reliable 4+ GPU offers, unverified allowed, sort by num_gpus desc -vastai search offers 'reliability > 0.99 num_gpus>=4 verified=False rented=any' -o 'num_gpus-' +vastai search offers 'reliability > 0.99 num_gpus>=4 verified=False' -o 'num_gpus-' # arm64 cpu architecture only vastai search offers 'cpu_arch=arm64' @@ -179,7 +179,7 @@ bool = True | False | `has_sla` | bool | restrict to offers with SLA enabled (`true`) or without (`false`) | | `target_reliability` | float | REST and console only. The current CLI sends this as an operator object and search rejects it (HTTP 400). See the Warning under Examples. | | `rentable` | bool | is the instance currently rentable | -| `rented` | bool | allow/disallow duplicates and potential conflicts with existing stopped instances | +| `rented` | bool | Returned on each offer. Not a filter. The server drops `rented` in the query. | | `storage_cost` | float | storage cost in $/GB/month | | `static_ip` | bool | is the IP addr static/stable | | `total_flops` | float | total TFLOPs from all GPUs | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 2c8adc7e..30ac4091 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -230,7 +230,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ }' ``` -The CLI default query sends `external=false rentable=true verified=true rented=false` (the `--help` text omits `rented`; see [search offers](/cli/reference/search-offers)). REST `POST /api/v0/bundles/` does **not** filter on `rented`. The server drops that key and returns a `rented` flag on each offer. Drop rows where `rented` is true if you need to hide GPUs you already rent. The CLI `rented=false` default does that filtering in the client. The response includes `truncated`. When it is `true`, the server cut the result short of `limit`. Narrow the query instead of assuming you saw every offer. +The CLI default query is `external=false rentable=true verified=true`. Neither the CLI nor the server filters on `rented`. REST `POST /api/v0/bundles/` drops that key and still returns a `rented` flag on each offer. Drop rows where `rented` is true if you need to hide GPUs you already rent. The response includes `truncated`. When it is `true`, the server cut the result short of `limit`. Narrow the query instead of assuming you saw every offer. **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: @@ -299,7 +299,8 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | -| Too many requests | HTTP 429. Detect throttling by the status code. The body differs by endpoint, so do not parse a `detail` field. Stay at or below about 10 search requests per minute per IP. If a `Retry-After` header is present, honor it. Space rent calls at least 5 seconds apart. A burst can block you for longer than that spacing. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Too many requests | HTTP 429. Detect throttling by the status code. The body differs by endpoint, so do not parse a `detail` field. Stay at or below about 10 search requests per minute per IP. If a `Retry-After` header is present, honor it. The CLI and SDK do not read that header. Space rent calls at least 5 seconds apart. A burst can block you for longer than that spacing. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Client retried the rent | The CLI and SDK retry timeouts and HTTP 502, 503, and 504, and they do not read `Retry-After`. | For an SLA rent, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | | Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message includes `error 403/3586` ("Hosts can only rent their own machines"). The HTTP status is 400, not 403. A host-only key gets this for every offer that is not on its own machines, including a missing offer. | Switch to a renter account key, then re-search (see [Hosting Overview](/host/hosting-overview) self-test note). | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f3064036..0410a281 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -45,7 +45,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. On SLA rentals, compute pay is not in `gpu_earn`. Much of the escrow can stay held until the contract ends, so a low `sla_earn` over several days is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. 7. Enter **Claim** and **Confidence**. Enter Claim in the units the console field shows. In the API, 99% is `0.99`, not `99`. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. -8. **Verify now.** From the client account, search with a **Reliability target** and confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). +8. **Verify now.** From the client account, include unverified machines (a new machine usually is) and set **Reliability target** at or below your Claim. Search hides offers whose Claim is below the target. Confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -89,7 +89,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. If it met the renter's target, you keep the SLA fee and no credit is paid. If it fell short, the renter receives a **service credit** from your earnings. After a stretch of good uptime, a single bad day can cost you a smaller credit than that day's raw uptime suggests. Even when raw uptime is at or slightly above the target, you can still owe a partial credit if the blended measure is below it. +6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. If it met the renter's target, you keep the SLA fee and no credit is paid. If it fell short, the renter receives a **service credit** from your earnings. On an SLA rental, compute pay is not in `gpu_earn`. It is released over time as `sla_earn`, and much of it can stay held until the contract ends. A low `sla_earn` day is not by itself a credit. 7. One bad day can cost more than many days of fees. What this is not: @@ -186,7 +186,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r ### Confidence values -**Confidence** sets how wide a pricing margin is built into the SLA fee around your reliability commitment. **Tight** means a smaller fee and less fee income for you. **Wide** means a larger fee. Confidence never changes the credit you owe when a renter's target is missed. The API field is `sla_sigma_x` (σ): a lower value is tighter. Backtester `p` runs the other way: a higher value is tighter. `show machines` uses `high`, `medium`, and `low` (`low` is Wide). Prefer the console controls. Set raw `sla_sigma_x` via the API when automating. +In the console, pick **Tight**, **Normal**, or **Wide**. You do not need the table unless you use the API or the backtester. | Console label | API `sla_sigma_x` (σ) | Backtester `p` | `show machines` | Pricing effect | | --- | --- | --- | --- | --- | @@ -760,7 +760,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Console** 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). - 2. Write down Claim, Confidence, prices, end date, reserved discount, and min bid from **Set Pricing**. + 2. Write down Claim, Confidence, GPU price, storage price, upload and download bandwidth prices, min GPU count, end date, whether the listing is hidden, reserved discount, and min bid from **Set Pricing**. A relist that omits bandwidth can publish it at $0, and omitting min GPU can slice the machine into 1-GPU offers. 3. Unlist only if the machine is still online and you need to stop new rentals. If it is offline, `create_asks` returns HTTP 402 until the daemon reconnects, and unlisting drops the SLA ask you would then have to rebuild. 4. Fix the problem. 5. After the next UTC midnight, check **Host → Billing** for that day's SLA earnings. diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 8a982c0f..b3d6a4e0 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -55,11 +55,13 @@ The SDK includes two clients with different retry strategies. The main `VastAI` client retries on rate limit responses: -- **Retried status codes:** 429 only +- **Retried status codes:** 429, 502, 503, and 504, plus connection errors and timeouts - **Default retries:** 3 -- **Backoff strategy:** starts at 0.15 seconds, multiplied by 1.5x after each attempt +- **Backoff strategy:** starts at 0.15 seconds, multiplied by 1.5x after each attempt. The SDK does not read `Retry-After`. - **Retry delays:** ~0.15s, ~0.225s, ~0.34s +For SLA rentals, a timeout or 5xx retry can send the same rent twice. Set a unique label and check instances for that label before you rent again. + ```python from vastai import VastAI diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 905c4797..b33e328b 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -17,7 +17,7 @@ On an existing listing, omitted GPU price, bandwidth prices, reserved discount, **Other cautions:** - **Passing `-e` or `-l` can extend active rentals,** including SLA contracts. Normal CLI output does not print that. Pass `--raw` and read `.results[0].upd_contracts`. -- **`-m` is required.** Omitting it returns HTTP 400 `invalid_args`. +- **`-m` defaults to 1.** On an existing listing that has no effect. On a first listing, or a relist after unlist, it splits the machine into single-GPU offers, and each one can be its own SLA contract. Always pass `-m` with the min GPU count you intend. - **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores listed SLA offers that are missing from search, on machines with no rentals. It does not change prices. A hidden listing is also missing from search, so set `HIDDEN_IDS` or the live run makes it public. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index c84300d7..d65e3511 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so Claim and Confidence stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. To keep auto-renew, pass `duration` again (seconds or a string such as `"30 days"`) on every call. Never pass `duration` together with `end_date`. `end_date` accepts a date string or a Unix timestamp. Pass `min_chunk` as well (null `min_chunk` is HTTP 400). Update hidden SLA listings with REST and send `hidden_listing` explicitly. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so Claim and Confidence stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. To keep auto-renew, pass `duration` again (seconds or a string such as `"30 days"`) on every call. Never pass `duration` together with `end_date`. Pass `min_chunk` as well. If you omit it, the SDK sends null and the server returns HTTP 400. The packaged CLI instead defaults `-m` to 1, which on a new ask splits the machine into single-GPU offers. `end_date` must be a Unix timestamp in seconds (`int` or `float`). Date strings such as `MM/DD/YYYY` are only converted by the CLI's `-e` flag. Update hidden SLA listings with REST and send `hidden_listing` explicitly. ## Signature @@ -18,11 +18,11 @@ VastAI.list_machine( discount_rate: Optional[float] = None, min_chunk: Optional[int] = None, price_min_bid: Optional[float] = None, - end_date: Optional[Union[str, int, float]] = None, + end_date: Optional[float] = None, duration: Optional[Union[str, int]] = None, vol_size: Optional[int] = None, vol_price: Optional[float] = None, -) -> str +) -> dict ``` ## Parameters @@ -60,7 +60,7 @@ VastAI.list_machine( - Offer expiration (Unix timestamp or MM/DD/YYYY). Do not pass together with `duration`. Sending it extends shorter active rentals. + Offer expiration as a Unix timestamp in seconds. Do not pass a date string. Do not pass together with `duration`. Sending it extends shorter active rentals. From 4e04432cb4444da0e3b74c67f55a60975629b5cd Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 00:42:03 -0700 Subject: [PATCH 199/250] docs(sla): address doc-review consensus (cycle 144) Treat CLI retry as attempt count, and warn that a new fleet ask resets confidence to 0.5. Co-authored-by: Cursor --- cli/rate-limits.mdx | 19 ++++++++----------- guides/instances/choosing/sla-coverage.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 10 +++++----- sdk/python/rate-limits.mdx | 19 ++++++++----------- snippets/host/sdk/list-machine.mdx | 6 +++--- 7 files changed, 27 insertions(+), 33 deletions(-) diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 470cca82..f0ab16f2 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -3,7 +3,7 @@ title: "CLI Rate Limits and Errors" sidebarTitle: "Rate Limits" --- -The Vast.ai CLI automatically retries rate-limited requests. You do not need to implement your own retry logic -- the CLI handles HTTP 429 responses with exponential backoff out of the box. +The Vast.ai CLI retries some failed requests. Those retries finish in under a second and do not read `Retry-After`. For offer search, rent, `create_asks`, and maintenance scheduling, add your own spacing. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). This page covers the error format, how rate limits work, and how to configure the CLI's built-in retry behavior. For the full details on rate limit mechanics, see the [API Rate Limits and Errors](/api-reference/rate-limits-and-errors) page. @@ -49,10 +49,10 @@ Some HTTP 429 responses include a `Retry-After` header. The daily search row quo When the CLI receives an HTTP 429 response, it automatically retries the request using exponential backoff: -- **Retried status codes:** 429, 502, 503, and 504, plus connection errors and timeouts -- **Default retries:** 3 -- **Backoff strategy:** starts at 0.15 seconds, multiplied by 1.5x after each attempt. The CLI does not read `Retry-After`. -- **Retry delays:** ~0.15s, ~0.225s, ~0.34s +- `--retry` is the **total number of attempts**, not extra retries after the first try. +- **Default:** 3 attempts (one request plus two retries), with delays of about 0.15 s and 0.225 s. +- **Backoff:** starts at 0.15 seconds, multiplied by 1.5 after each attempt. The CLI does not read `Retry-After`. +- To send a request once, use `--retry 1`. Do not use `--retry 0`. It sends no request and the command fails. For SLA rentals, a timeout or 5xx retry can send the same rent twice. Set a unique label and check instances for that label before you rent again. See [SLA](/guides/instances/choosing/sla-coverage). @@ -65,14 +65,11 @@ The CLI retries 429, 502, 503, and 504. Other HTTP errors are reported immediate Use the `--retry` flag on any command to change the number of retry attempts: ```bash -# Use default 3 retries +# Default: 3 attempts vastai search offers 'gpu_name=RTX_4090 rentable=true' -# Increase to 6 retries for a batch script -vastai search offers 'gpu_name=RTX_4090 rentable=true' --retry 6 - -# Disable retries entirely -vastai search offers 'gpu_name=RTX_4090 rentable=true' --retry 0 +# One attempt only (use this when you must not send a rent twice) +vastai search offers 'gpu_name=RTX_4090 rentable=true' --retry 1 ``` Increasing the retry count is useful for scripts that make many API calls in sequence, where occasional rate limiting is expected. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 30ac4091..4f6622b6 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -282,7 +282,7 @@ curl -G "https://console.vast.ai/api/v1/instances/" \ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row (`target_reliability > 0` means the rental has an SLA). `instance.slaPremiumPerHour` is `0` until the instance is **running**, so do not treat `0` before startup as a failed SLA rent. Once it is running, that field is the SLA fee. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, confirm you used `new_contract` (not the offer id), then retry after a short delay, no more than about once per second (`show_instances` `x-rate-limit` threshold `1.0`). Use `after_token` paging only when listing without an `id` filter. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). If you omit `limit`, the server returns at most **25** rows. A non-positive `limit` is treated as 5, then capped at 25. -- **CLI** (`vastai show instances-v1`): use `--limit` and `--next-token`. The CLI default `--limit` is **25** unless you set it. +- **CLI:** `vastai show instances --raw` fetches every page by default (`show instances-v1` is a hidden alias for the same command). Passing `--limit` (1–25) or `--next-token` switches to a single page. **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 73d2b2e5..ff0f0e7a 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -42,7 +42,7 @@ Clients have high expectations coming from AWS or GCP. As a host, plan to offer ## Offers and Rental Contracts -Hosts can create offers (sometimes called listings; the API calls an offer an **ask**) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). A reliability commitment and confidence require **Set Pricing → SLA** in the console or `PUT /api/v0/machines/create_asks/` — not `vastai list machine` today (see [SLA Offers](/host/sla-offers)). Repricing an already-listed SLA machine with the CLI keeps the current SLA terms, but omitting `-l` clears auto-renew and omitting `-v` can create a volume offer. A relist after unlist creates a new ask without SLA. +Hosts can create offers (sometimes called listings; the API calls an offer an **ask**) through the CLI command `list machine` or the GUI on the [host machines page](https://cloud.vast.ai/host/machines). SLA terms are set in **Set Pricing → SLA** or through the REST API, not with `vastai list machine`. Before repricing from the CLI, read the [`list machine` caveats](/host/cli/list-machine): some omitted flags reset your storage price, auto-renew, or hidden status. A relist after unlist creates a new ask without SLA. The main offer parameters include: diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 825533fb..d1767f2e 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -280,7 +280,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** ## Fleet workflow -Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. For machines that already have SLA enabled, the replay under-counts those days. Treat `net_sla` and `largest_day_credit` as a lower bound, or set the window to dates from before SLA was enabled. See [Simulation limits](#simulation-limits). +Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. For machines that already have SLA enabled, the replay under-counts those days. Treat `largest_day_credit` as a lower bound. `net_sla` can be off in either direction, because both fees and credits are understated. For a cleaner estimate, use a window from before SLA was enabled. See [Simulation limits](#simulation-limits). **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 0410a281..ce19c7e7 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -42,7 +42,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** (your reliability commitment, the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA or Claim section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. -5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. On SLA rentals, compute pay is not in `gpu_earn`. Much of the escrow can stay held until the contract ends, so a low `sla_earn` over several days is not by itself a credit. +5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. 7. Enter **Claim** and **Confidence**. Enter Claim in the units the console field shows. In the API, 99% is `0.99`, not `99`. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. 8. **Verify now.** From the client account, include unverified machines (a new machine usually is) and set **Reliability target** at or below your Claim. Search hides offers whose Claim is below the target. Confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). @@ -405,7 +405,7 @@ Each live PUT resends the offer's `end_date` (or `duration`). Any active rental The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute per IP. The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. -`show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, `create_asks` keeps the current confidence when `sla_sigma_x` is omitted, so each machine keeps its exact value. Set a new confidence per machine in the console (or PUT `sla_sigma_x` for that machine) if you want to change it. +`show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, omitting it keeps the current confidence. If the PUT creates a **new** ask, the server sets `sla_sigma_x` to `0.5` unless you send it. Keep your own record of each machine's σ and check **Set Pricing → SLA** after any run that logs a new ask. `PUT /api/v0/machines/create_asks/` **publishes a live listing** (same as **LIST**). The loop skips machines whose `listed` field is not `true`, so it does not republish machines you unlisted. Still keep an `ALLOWLIST` of the machine IDs you intend to automate, and confirm them on **Host → Machines** before you run with `DRY_RUN=0`. @@ -540,7 +540,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ "$ok" = "true" ]; then echo "machine_id=$id ok extended=$(echo "$resp" | jq -c '.results[0].upd_contracts // []')" if echo "$resp" | jq -e '.results[0].new_contracts | length > 0' >/dev/null; then - echo "WARN machine_id=$id: re-list created a new ask; confirm bandwidth, credit_discount_max, and price_min_bid" >&2 + echo "WARN machine_id=$id: re-list created a new ask; confirm bandwidth, credit_discount_max, price_min_bid, and confidence (a new ask defaults sla_sigma_x to 0.5)" >&2 fi else echo "machine_id=$id error: $(echo "$resp" | jq -c '{success, error: (.error // .results[0].error), msg: (.msg // .results[0].msg)}' 2>/dev/null || echo "$resp")" @@ -653,7 +653,7 @@ Settlement uses a **blended** reliability measure (recent plus longer-term uptim Example: you publish **reliability commitment 99%**, the client chose **target 95%**, and the **blended** measure is **~97%**. - **Credits** are evaluated against the client's **target** (95%), not your reliability commitment. -- Because that blended 97% is above 95%, you **owe no SLA credit** for that day. Even when raw uptime is in the same range, you can still owe a partial credit if the blended measure is below the target. +- Because that blended 97% is above 95%, you **owe no SLA credit** for that day. Raw uptime alone does not decide this: a day with 97% raw uptime can still carry a partial credit if the blended measure falls below the target. - **SLA fees** are priced from your **reliability commitment**, confidence, and the client's target — a higher reliability commitment relative to the target generally means lower client charges. The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what drives service-credit eligibility. @@ -763,7 +763,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 2. Write down Claim, Confidence, GPU price, storage price, upload and download bandwidth prices, min GPU count, end date, whether the listing is hidden, reserved discount, and min bid from **Set Pricing**. A relist that omits bandwidth can publish it at $0, and omitting min GPU can slice the machine into 1-GPU offers. 3. Unlist only if the machine is still online and you need to stop new rentals. If it is offline, `create_asks` returns HTTP 402 until the daemon reconnects, and unlisting drops the SLA ask you would then have to rebuild. 4. Fix the problem. - 5. After the next UTC midnight, check **Host → Billing** for that day's SLA earnings. + 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. **API** diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index b3d6a4e0..2a93a986 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -3,7 +3,7 @@ title: "SDK Rate Limits and Errors" sidebarTitle: "Rate Limits" --- -The Vast.ai SDK automatically retries rate-limited requests. You do not need to implement your own retry logic -- both the `VastAI` client and the serverless client handle retries with exponential backoff out of the box. +The Vast.ai SDK retries some failed requests. Those retries finish in under a second and do not read `Retry-After`. For offer search, rent, and listing calls, add your own spacing. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). This page covers the error format, how rate limits work, and how to configure retry behavior for each client. For the full details on rate limit mechanics, see the [API Rate Limits and Errors](/api-reference/rate-limits-and-errors) page. @@ -55,17 +55,17 @@ The SDK includes two clients with different retry strategies. The main `VastAI` client retries on rate limit responses: -- **Retried status codes:** 429, 502, 503, and 504, plus connection errors and timeouts -- **Default retries:** 3 -- **Backoff strategy:** starts at 0.15 seconds, multiplied by 1.5x after each attempt. The SDK does not read `Retry-After`. -- **Retry delays:** ~0.15s, ~0.225s, ~0.34s +- `retry` is the **total number of attempts**. +- **Default:** 3 attempts (one request plus two retries), with delays of about 0.15 s and 0.225 s. +- **Backoff:** starts at 0.15 seconds, multiplied by 1.5 after each attempt. The SDK does not read `Retry-After`. +- To send a request once, use `retry=1`. Do not use `retry=0`. It sends no request. For SLA rentals, a timeout or 5xx retry can send the same rent twice. Set a unique label and check instances for that label before you rent again. ```python from vastai import VastAI -# Uses default retry behavior (3 retries) +# Default: 3 attempts (2 retries) vast = VastAI(api_key="your-api-key") vast.search_offers(query="gpu_name=RTX_4090 rentable=true") ``` @@ -94,11 +94,8 @@ Pass the `retry` parameter to the constructor to change the number of retry atte ```python from vastai import VastAI -# Increase to 6 retries for a batch script -vast = VastAI(api_key="your-api-key", retry=6) - -# Disable retries entirely -vast = VastAI(api_key="your-api-key", retry=0) +# One attempt only +vast = VastAI(api_key="your-api-key", retry=1) ``` The retry count applies to all requests made through that client instance. diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index d65e3511..dec203a0 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -59,8 +59,8 @@ VastAI.list_machine( Per-GPU minimum bid (host-side). The value you read back as `min_bid_price` can differ slightly from what you sent. - - Offer expiration as a Unix timestamp in seconds. Do not pass a date string. Do not pass together with `duration`. Sending it extends shorter active rentals. + + Unix timestamp (UTC seconds). Do not pass a date string. Do not pass together with `duration`. Sending it extends shorter active rentals. @@ -77,7 +77,7 @@ VastAI.list_machine( ## Returns -`str`. The return value is the API response body as text (JSON). +`dict` — the parsed JSON response body. On HTTP errors the SDK raises `requests.HTTPError`. ## Example From 154398927e8cb884340e37f9d71ae501646c55e4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 00:52:32 -0700 Subject: [PATCH 200/250] docs(sla): address doc-review consensus (cycle 145) Treat list-machine dates as UTC, and stop telling hosts to look for an SLA line that Billing does not show. Co-authored-by: Cursor --- cli/rate-limits.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 8 ++++---- sdk/python/rate-limits.mdx | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index f0ab16f2..08839b9f 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -43,7 +43,7 @@ or API requests too frequent: endpoint threshold=... ``` -Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. When it is present, wait at least that long. When it is absent, the CLI uses its own backoff. +Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. The CLI never reads that header. Its own retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. ## Built-in Retry Behavior diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index ff0f0e7a..d0d91f41 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. Existing contracts keep their original end dates in some cases, for example when the relist raises a price or changes SLA terms. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. Existing contracts keep their original end dates in some cases, for example when the relist raises a price, or changes Claim or Confidence in a way that would raise that contract's SLA fee. A contract skipped for an SLA-fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index ce19c7e7..08638eb6 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -335,7 +335,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ }' ``` -Replace `end_date` with the listing's current Unix timestamp from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e` (parsed in the local time zone of the computer running the CLI, not UTC). Use a Unix timestamp for an exact UTC end. +Replace `end_date` with the listing's current Unix timestamp from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`, read as 00:00 UTC on that date, not your local time zone. `vastai show earnings --start_date` and `--end_date` are different: bare dates there are parsed in the local time zone of the computer running the CLI. Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). @@ -764,7 +764,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist only if the machine is still online and you need to stop new rentals. If it is offline, `create_asks` returns HTTP 402 until the daemon reconnects, and unlisting drops the SLA ask you would then have to rebuild. 4. Fix the problem. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. - 6. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. + 6. Relist only if you unlisted in step 3. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. **API** @@ -793,7 +793,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep ## Monitoring SLA after listing -After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. SLA earnings rows typically appear in **Host → Billing** within a few hours after UTC midnight (exact timing can vary). +After you enable SLA, charges and credits settle on UTC (Coordinated Universal Time) day boundaries. **Host → Billing** does not show a separate SLA line. Fees you keep and credits you owe are folded into the daily earnings total, which usually updates within a few hours after UTC midnight. Compare a day with a normal week. For the SLA amount on one machine, use the CLI or API below (`sla_earn`). **Reading `sla_earn`** @@ -811,7 +811,7 @@ After you enable SLA, charges and credits settle on UTC (Coordinated Universal T 4. Look for the SLA settlement in the earnings breakdown. On an SLA rental, compute pay is released with the SLA fee (the same amount as `sla_earn` in the API), not as a separate GPU earnings line. 5. After downtime, compare several days with a normal week. Much of the escrow can stay held until the contract ends, so a low `sla_earn` is not by itself a credit. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. -**If you don't see SLA rows:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). +**If the daily total looks wrong:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). There is still no separate SLA row on the normal Host → Billing view. SLA settlement does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 2a93a986..8133077b 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -45,7 +45,7 @@ or API requests too frequent: endpoint threshold=... ``` -Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. When it is present, wait at least that long. When it is absent, the SDK uses its own backoff. +Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. The SDK never reads that header. Its own retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. ## Built-in Retry Behavior From 6ab5e37a74f227e9805df66afb0d2eab11f36893 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 01:03:35 -0700 Subject: [PATCH 201/250] docs(sla): address doc-review consensus (cycle 146) Say what the CLI and SDK actually retry, and stop pointing console hosts at an SLA billing line that is not there. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/rate-limits.mdx | 14 +++++++------- guides/instances/choosing/sla-coverage.mdx | 18 ++++++++++++------ host/hosting-overview.mdx | 4 ++-- host/sla-offers.mdx | 6 +++--- sdk/python/rate-limits.mdx | 8 ++++---- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 2 +- 8 files changed, 31 insertions(+), 25 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index afc31a0c..7b103382 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -121,7 +121,7 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if | Rent with an SLA | `instance_write` | Console **RENT** | | Verify `target_reliability` | `instance_read` | **Instances** | -**Service credits:** **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net row. The call requires `select_filters` with both `day.gte` and `day.lte` (unix seconds, UTC). A call without that range returns HTTP 400. The response can include `results[].items[]` rows with `type: "sla"`. Each row is the SLA fee minus any service credit. The console labels a negative amount **Service Credit** and any other amount **SLA Fee**. A credit smaller than the fee is a smaller **SLA Fee** row, not a separate line. The row is omitted until the last day in the window has settled. Page by sending `next_token` as `after_token`. Stop when `next_token` is `null`. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. +**Service credits:** **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net row. How that row is labeled is in [Settlement timing](/guides/instances/choosing/sla-coverage#settlement-timing). The call requires `select_filters` with both `day.gte` and `day.lte` (unix seconds, UTC). A call without that range returns HTTP 400. The row is omitted until the last day in the window has settled. Page by sending `next_token` as `after_token`. Stop when `next_token` is `null`. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. ```bash curl -G "https://console.vast.ai/api/v0/charges/" \ diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 08839b9f..0bda9393 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -3,7 +3,7 @@ title: "CLI Rate Limits and Errors" sidebarTitle: "Rate Limits" --- -The Vast.ai CLI retries some failed requests. Those retries finish in under a second and do not read `Retry-After`. For offer search, rent, `create_asks`, and maintenance scheduling, add your own spacing. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). +The Vast.ai CLI retries some failed requests. With the default of 3 attempts, those retries finish in under a second and do not read `Retry-After`. For offer search, rent, `create_asks`, and maintenance scheduling, add your own spacing. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). This page covers the error format, how rate limits work, and how to configure the CLI's built-in retry behavior. For the full details on rate limit mechanics, see the [API Rate Limits and Errors](/api-reference/rate-limits-and-errors) page. @@ -43,21 +43,21 @@ or API requests too frequent: endpoint threshold=... ``` -Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. The CLI never reads that header. Its own retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. +Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. The CLI never reads that header. With the default of 3 attempts, those retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. ## Built-in Retry Behavior -When the CLI receives an HTTP 429 response, it automatically retries the request using exponential backoff: +The CLI retries a failed request on HTTP 429, 502, 503, and 504, and on connection errors and timeouts. With the default of 3 attempts, those retries finish in under a second. It never reads `Retry-After`. - `--retry` is the **total number of attempts**, not extra retries after the first try. - **Default:** 3 attempts (one request plus two retries), with delays of about 0.15 s and 0.225 s. - **Backoff:** starts at 0.15 seconds, multiplied by 1.5 after each attempt. The CLI does not read `Retry-After`. - To send a request once, use `--retry 1`. Do not use `--retry 0`. It sends no request and the command fails. -For SLA rentals, a timeout or 5xx retry can send the same rent twice. Set a unique label and check instances for that label before you rent again. See [SLA](/guides/instances/choosing/sla-coverage). +Any rent can be sent twice if the first request reached the server and the connection then failed. Set a unique `--label` and check your instances for it before you rent again. The CLI and SDK cannot turn SLA on; SLA rentals use the console or REST. Use the same label check in your own retry logic. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). -The CLI retries 429, 502, 503, and 504. Other HTTP errors are reported immediately. +The CLI retries 429, 502, 503, 504, connection errors, and timeouts. Other HTTP errors are reported immediately. ## Configuring Retries @@ -68,11 +68,11 @@ Use the `--retry` flag on any command to change the number of retry attempts: # Default: 3 attempts vastai search offers 'gpu_name=RTX_4090 rentable=true' -# One attempt only (use this when you must not send a rent twice) +# One attempt only vastai search offers 'gpu_name=RTX_4090 rentable=true' --retry 1 ``` -Increasing the retry count is useful for scripts that make many API calls in sequence, where occasional rate limiting is expected. +Raising `--retry` does not replace your own request spacing. On a rent, each extra attempt can send the request again. ## Reducing Rate Limit Errors diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 4f6622b6..6f25f2f7 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -198,7 +198,7 @@ Search quotes SLA; renting with SLA requires REST (or the console) with `target_ | Search / quote an SLA | Yes | Yes (`POST /api/v0/bundles/`) | | Enable an SLA at rent | Yes | Yes (`target_reliability` on `PUT /api/v0/asks/{id}/`) | | Verify the SLA on an instance | Yes | Yes (`GET /api/v1/instances/`) | -| SLA settlement | **Account → Billing → Charges** (same net row as the API) | `results[].items[].type` `sla` is the SLA fee minus any service credit. The console labels a negative amount **Service Credit** and any other amount **SLA Fee**. Not in invoices or client webhooks. | +| SLA settlement | **Account → Billing → Charges** | Same net `type: "sla"` row as the API. How it is labeled, and why it is missing from invoices, is in [Settlement timing](#settlement-timing). | **Rent body (SLA):** Among SLA-related fields, send only `target_reliability` (not `sla_r_claim` / `sla_r_target`). Still include `image` or `template_hash_id` and a `disk` that matches your search quote. @@ -232,6 +232,12 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ The CLI default query is `external=false rentable=true verified=true`. Neither the CLI nor the server filters on `rented`. REST `POST /api/v0/bundles/` drops that key and still returns a `rented` flag on each offer. Drop rows where `rented` is true if you need to hide GPUs you already rent. The response includes `truncated`. When it is `true`, the server cut the result short of `limit`. Narrow the query instead of assuming you saw every offer. +Server-side sort by `dph_total` puts offers that could not be SLA-priced first, because they have no SLA fee. Drop them, then sort again. You may need a larger `limit` to make up for the dropped rows. + +```bash +curl ... | jq '.offers | map(select((.search.slaPremiumPerHour // 0) > 0)) | sort_by(.dph_total)' +``` + **2. Rent** the chosen offer. Use `offers[].id` from the search response as `{id}` in `PUT /api/v0/asks/{id}/`. Prefer `id` over `ask_contract_id` when both appear. Never use `bundle_id`. Save `new_contract` from the rent response. Pass the **same** reliability target you searched with: ```bash @@ -286,9 +292,9 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. -**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Each Charges row is one contract. Match `source` to `instance-` plus the contract ID from `new_contract` (or `metadata.label` if you set a unique label at rent), then read the `sla` item in `items[]`. Store the hourly SLA fee when the rent succeeds: `search.slaPremiumPerHour` on the `GET /api/v1/instances/` row for that contract. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. Expected fee for a UTC day is about the stored rate times the hours the contract was active, including downtime. A `sla` row smaller than that, or negative, means a credit was applied. **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. +**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Each Charges row is one contract. Match `source` to `instance-` plus the contract ID from `new_contract` (or `metadata.label` if you set a unique label at rent), then read the `sla` item in `items[]`. Store the hourly SLA fee when the rent succeeds: `search.slaPremiumPerHour` on the `GET /api/v1/instances/` row for that contract. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. Expected fee for a UTC day is about the stored rate times the hours the contract was active, including downtime. A `sla` row smaller than that, or negative, means a credit was applied. How the console labels that row is in [Settlement timing](#settlement-timing). The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. -**Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read the same net `type: "sla"` row from **Account → Billing → Charges** or `GET /api/v0/charges/` (see the billing reconciliation paragraph above). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). +**Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read Charges after settlement (see [Settlement timing](#settlement-timing)). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). | Symptom | Typical response | What to do | | --- | --- | --- | @@ -300,7 +306,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | | Too many requests | HTTP 429. Detect throttling by the status code. The body differs by endpoint, so do not parse a `detail` field. Stay at or below about 10 search requests per minute per IP. If a `Retry-After` header is present, honor it. The CLI and SDK do not read that header. Space rent calls at least 5 seconds apart. A burst can block you for longer than that spacing. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | -| Client retried the rent | The CLI and SDK retry timeouts and HTTP 502, 503, and 504, and they do not read `Retry-After`. | For an SLA rent, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | +| CLI or SDK retried a rent on its own | The CLI and SDK retry connection errors, timeouts, and HTTP 429, 502, 503, and 504. They do not read `Retry-After`. They cannot set `target_reliability`. | For an SLA rent you send yourself, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | | Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | | Forbidden / wrong account | HTTP 400 `invalid_args`. The message includes `error 403/3586` ("Hosts can only rent their own machines"). The HTTP status is 400, not 403. A host-only key gets this for every offer that is not on its own machines, including a missing offer. | Switch to a renter account key, then re-search (see [Hosting Overview](/host/hosting-overview) self-test note). | @@ -320,7 +326,7 @@ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** be When you rent an SLA-backed offer **with a target set**: 1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA fee line or `dph_total`. Host confidence is not shown in the web console and is not a setting you control. -2. **Charges and settlement** — compute, storage, and the SLA fee accrue while the rental contract is active, **including while the machine is offline**. That is different from a non-SLA rental. Only service credits are settled once per UTC day. See [What you pay during an outage](#what-you-pay-during-an-outage). +2. **Charges and settlement** — compute, storage, and the SLA fee accrue while the rental contract is active, **including while the machine is offline**. That is different from a non-SLA rental. The net SLA row (SLA fee minus any service credit) settles once per UTC day. See [Settlement timing](#settlement-timing) and [What you pay during an outage](#what-you-pay-during-an-outage). 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA fee with no credit. @@ -452,7 +458,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta **Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. Compare it with **SLA Fee/hr** × the hours the contract was active that UTC day, including downtime. The Charges API returns the same net. Invoices do not. You cannot see the measured reliability for that day in the console or the API. -**API integrators:** **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net. `results[].items[]` with `type: "sla"` is the SLA fee minus any service credit. The console labels a negative amount **Service Credit** and any other amount **SLA Fee**. A row below the fee you expected means a credit was applied. The row is omitted until the window's last day has settled. The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). +**API integrators:** Use the same Charges row as [Settlement timing](#settlement-timing). The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. A row below the fee you expected means a credit was applied. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). ## Related documentation diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index d0d91f41..0a4a531c 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -252,12 +252,12 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. - **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. You cannot see which active rentals carry an SLA. If SLA was on at any point during a rental that is still active, use the SLA path below. -- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It only stops new rentals, and it removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter Claim and Confidence before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It stops new rentals, and it also removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter Claim and Confidence before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: 1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. -2. **Planned downtime with active renters:** Schedule as far ahead as you can from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). Twenty-four hours is not a forgiveness cutoff. +2. **Planned downtime with active renters:** Schedule as far ahead as you can from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). 3. **Emergency or unplanned downtime:** Notify renters immediately, either from the console ([Set a maintenance window](/host/set-maintenance-window)) or with [`vastai schedule maint`](/host/cli/schedule-maint). Use one path per window. For SLA maintenance-forgiveness rules, notice windows, and confirmation steps, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Forgiveness is not guaranteed, and it is not a payment to the host. Optional: configure [Host Notifications](/host/notifications) for `host:maintenance_scheduled`. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 08638eb6..e553f56c 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -43,7 +43,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. -6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. +6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. Enter **Claim** and **Confidence**. Enter Claim in the units the console field shows. In the API, 99% is `0.99`, not `99`. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. 8. **Verify now.** From the client account, include unverified machines (a new machine usually is) and set **Reliability target** at or below your Claim. Search hides offers whose Claim is below the target. Confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. @@ -707,7 +707,7 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **Or use CLI/REST below.** Forgiveness is not guaranteed either way. -**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). There is no notice cutoff that fully forgives the window. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. Include `duration` (whole hours) and `maintenance_category`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. +**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Notice rules are in the note above. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. Include `duration` (whole hours) and `maintenance_category`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. **`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -808,7 +808,7 @@ After you enable SLA, charges and credits settle on UTC (Coordinated Universal T 1. Go to **Host → Billing**. 2. Set the date range to include the UTC day you want to review. 3. Machine filtering is not available in the console. For one machine, use `vastai show earnings --machine_id ID`. -4. Look for the SLA settlement in the earnings breakdown. On an SLA rental, compute pay is released with the SLA fee (the same amount as `sla_earn` in the API), not as a separate GPU earnings line. +4. SLA fees you keep and credits you owe are folded into the daily earnings total. There is no separate SLA line. Compare the total with a normal week. For one machine's SLA amount, run `vastai show earnings --machine_id ID` and read `sla_earn`. 5. After downtime, compare several days with a normal week. Much of the escrow can stay held until the contract ends, so a low `sla_earn` is not by itself a credit. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. **If the daily total looks wrong:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). There is still no separate SLA row on the normal Host → Billing view. diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 8133077b..f91f183c 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -3,7 +3,7 @@ title: "SDK Rate Limits and Errors" sidebarTitle: "Rate Limits" --- -The Vast.ai SDK retries some failed requests. Those retries finish in under a second and do not read `Retry-After`. For offer search, rent, and listing calls, add your own spacing. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). +The Vast.ai SDK retries some failed requests. With the default of 3 attempts, those retries finish in under a second and do not read `Retry-After`. For offer search, rent, and listing calls, add your own spacing. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). This page covers the error format, how rate limits work, and how to configure retry behavior for each client. For the full details on rate limit mechanics, see the [API Rate Limits and Errors](/api-reference/rate-limits-and-errors) page. @@ -45,7 +45,7 @@ or API requests too frequent: endpoint threshold=... ``` -Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. The SDK never reads that header. Its own retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. +Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. The SDK never reads that header. With the default of 3 attempts, those retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. ## Built-in Retry Behavior @@ -53,14 +53,14 @@ The SDK includes two clients with different retry strategies. ### VastAI Client -The main `VastAI` client retries on rate limit responses: +The main `VastAI` client retries on HTTP 429, 502, 503, and 504, and on connection errors and timeouts: - `retry` is the **total number of attempts**. - **Default:** 3 attempts (one request plus two retries), with delays of about 0.15 s and 0.225 s. - **Backoff:** starts at 0.15 seconds, multiplied by 1.5 after each attempt. The SDK does not read `Retry-After`. - To send a request once, use `retry=1`. Do not use `retry=0`. It sends no request. -For SLA rentals, a timeout or 5xx retry can send the same rent twice. Set a unique label and check instances for that label before you rent again. +Any rent can be sent twice if the first request reached the server and the connection then failed. Set a unique `label` and check your instances for it before you rent again. The SDK cannot turn SLA on; SLA rentals use the console or REST. Use the same label check in your own retry logic. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). ```python from vastai import VastAI diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index b33e328b..9c1941ef 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -95,7 +95,7 @@ We strongly recommend you test the machine first and only list when ready. Alway # Reprice without extending rentals. Omitting -e sends no new end date. # Pass -l again only if this listing auto-renews. Omitting -l clears auto-renew. vastai list machine -g 3.50 -s -m -v 0 -# Extend the offer end date. -e extends every active rental that ends sooner, including SLA. +# Re-send the current end date. This does not move the offer end. It still extends shorter active rentals up to that date, including SLA. vastai list machine -g 3.50 -s -m -v 0 -e ``` diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 72c50263..6f15f3e8 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -44,7 +44,7 @@ The same `schedule maint` command is used for both **planned** and **emergency** ### Planned SLA maintenance -If SLA is enabled and you need planned downtime during an active rental, schedule as far ahead as you can. Twenty-four hours is not a forgiveness cutoff. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). +If SLA is enabled and you need planned downtime during an active rental, schedule as far ahead as you can. See [SLA Offers → Scheduled maintenance](/host/sla-offers#scheduled-maintenance). ```bash # Replace MACHINE_ID; --sdate must be a future UTC epoch. From 6cd41ad8296f71c9175bea7045ebbfcde1e167a0 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 01:13:36 -0700 Subject: [PATCH 202/250] docs(sla): address doc-review consensus (cycle 147) Match maintenance duration and SDK errors to the server, and keep API jargon out of the console outage steps. Co-authored-by: Cursor --- api-reference/openapi.yaml | 10 +++++++--- .../openapi/yaml/schedule_maint.yaml | 7 ++++--- api-reference/rate-limits-and-errors.mdx | 4 ++-- host/sla-offers.mdx | 20 +++++++++---------- sdk/python/rate-limits.mdx | 2 +- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index cd29ca08..e11db514 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6422,7 +6422,6 @@ paths: type: object required: - sdate - - duration properties: sdate: type: number @@ -6435,8 +6434,13 @@ paths: ' example: 1785549600 duration: - type: integer - description: Duration of the maintenance window in hours. + type: number + description: 'Duration of the maintenance window in hours. If you + omit it, the server uses 1 hour. + + A fractional value is rounded down, with a minimum of 1 hour. + + ' example: 2 maintenance_reason: type: string diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index 4313a46e..1af415f6 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -34,7 +34,6 @@ paths: type: object required: - sdate - - duration properties: sdate: type: number @@ -43,8 +42,10 @@ paths: `1785549600` (2026-08-01 02:00 UTC). The CLI `--sdate` flag sends the same value. example: 1785549600 duration: - type: integer - description: Duration of the maintenance window in hours. + type: number + description: | + Duration of the maintenance window in hours. If you omit it, the server uses 1 hour. + A fractional value is rounded down, with a minimum of 1 hour. example: 2 maintenance_reason: type: string diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index 7ee2d97f..d863ef3b 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -23,9 +23,9 @@ Some omit `error` and return only `msg` or `message`. ### How rate limits are applied -Vast.ai applies rate limits **per endpoint** and **per identity**. This is enforced as a minimum interval between requests for a given endpoint and identity. +Vast.ai applies rate limits **per endpoint** and **per identity**. This is enforced as a minimum interval between requests for a given endpoint and identity. OpenAPI `x-rate-limit.threshold`, and the `threshold=` value in a 429 message, is that interval in seconds. -The identity is determined by: bearer token + session user + `api_key` query param + client IP. +For a signed-in API key, the limit is per user account. Extra keys on the same account do not raise it. A call that does not resolve to an account is limited by client IP. Some endpoints also use **method-specific** limits (GET vs POST) and/or **max-calls-per-period** limits for short bursts. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e553f56c..8def96b5 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -40,7 +40,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [Auto-renew and SLA](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** (your reliability commitment, the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA or Claim section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) if you schedule maintenance or read earnings from the CLI. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. +3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. @@ -70,7 +70,7 @@ Complete [host setup](https://cloud.vast.ai/host/setup/) first. A healthy machin Before enabling SLA, finish normal listing setup: test your machine, set GPU price and offer end date, choose on-demand vs interruptible, and understand [Testing your own machine](/host/hosting-overview#testing-your-own-machine) and offer terms in [Hosting overview](/host/hosting-overview). -On outage days you may still bill clients for **intended** compute **and** owe service credits. Tail-risk exposure can approach a full day’s compute per affected contract — not just the daily SLA fee shown in previews. Read [Billing vs settlement](#billing-vs-settlement-important) before enabling SLA. +On an outage day the renter is still charged the normal hourly rate, and you may also owe a service credit. Tail-risk exposure can approach a full day’s compute per affected contract — not just the daily SLA fee shown in previews. Read [Billing vs settlement](#billing-vs-settlement-important) before enabling SLA. @@ -89,7 +89,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. If it met the renter's target, you keep the SLA fee and no credit is paid. If it fell short, the renter receives a **service credit** from your earnings. On an SLA rental, compute pay is not in `gpu_earn`. It is released over time as `sla_earn`, and much of it can stay held until the contract ends. A low `sla_earn` day is not by itself a credit. +6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. If it met the renter's target, you keep the SLA fee and no credit is paid. If it fell short, the renter receives a **service credit** from your earnings. Vast holds SLA rental pay and releases it over time, so a low earnings day is not by itself a credit. Details are in [Billing vs settlement](#billing-vs-settlement-important). 7. One bad day can cost more than many days of fees. What this is not: @@ -140,7 +140,7 @@ On sliced machines, SLA settles **per rental contract**. If one GPU slice fails ### Billing vs settlement (important) -For SLA-covered on-demand contracts, compute billing uses the **intended daily compute** for the rental. Offline time is tracked as an outage in reliability observations. Client compensation for poor reliability flows through **service credits**, not by silently zeroing the day's compute bill. +For SLA-covered on-demand contracts, the renter is still charged the normal hourly rate during an outage. Vast does not zero that day's compute bill. Compensation is a service credit. **Where SLA money goes.** On an SLA rental, the renter's compute payment and SLA fee are held by Vast (escrow) instead of being paid to you right away. Service credits are paid from that held money, and the rest is released to you over the following days. Those earnings show up as **SLA** earnings (`sla_earn`), not GPU earnings. See [How SLA money moves](/host/sla-backtester#how-sla-money-moves). @@ -731,7 +731,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ `sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Otherwise a failed cancel plus a new window leaves duplicates. Windows Vast scheduled stay in place and are listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). +**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -760,9 +760,9 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Console** 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). - 2. Write down Claim, Confidence, GPU price, storage price, upload and download bandwidth prices, min GPU count, end date, whether the listing is hidden, reserved discount, and min bid from **Set Pricing**. A relist that omits bandwidth can publish it at $0, and omitting min GPU can slice the machine into 1-GPU offers. - 3. Unlist only if the machine is still online and you need to stop new rentals. If it is offline, `create_asks` returns HTTP 402 until the daemon reconnects, and unlisting drops the SLA ask you would then have to rebuild. - 4. Fix the problem. + 2. Write down every field on **Set Pricing** (price, minimum GPUs, end date, storage price, bandwidth, Claim, Confidence, reserved discount, and min bid). If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. + 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. + 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. 6. Relist only if you unlisted in step 3. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. @@ -787,7 +787,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If that `include_offline` response is also empty, use the console notes above. Do not unlist until you have the terms. 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. - 4. Fix the machine. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. + 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. 6. **Relist with every field resent.** Relisting after an unlist creates a new ask, so stored values do not carry over. Send all of these in one `create_asks` request, using the values you recorded before unlisting: `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `sla_r_claim`, `sla_sigma_x`, `credit_discount_max`, `price_min_bid`, and `"vol_size": 0` unless you want a volume offer. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. `show machines` never returns the exact `sla_sigma_x`. Sending `end_date` or `duration` extends every active rental that ends sooner. No API field shows the latest rental end date. Check **Host → Machines** before you choose it. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. @@ -846,7 +846,7 @@ Weekly aggregates are window totals, not daily series — use a one-day range ab ### API (automation) -**Console users:** Skip this section if you check billing in **Host → Billing**. No API key is required. +**Console users:** Skip this section for fleet-wide totals in **Host → Billing**. To see SLA results for one machine, use `vastai show earnings --machine_id ID` with an API key that has `billing_read`. **API keys for SLA** diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index f91f183c..b2e9cd93 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -21,7 +21,7 @@ The underlying API error shape is: Some endpoints omit `success` or `error` and return only `msg` or `message`. -The `VastAI` client returns the error as a dictionary when `raw=True` is set, or prints the message otherwise. The serverless client raises an exception after exhausting all retries. +After its built-in retries are used up, the `VastAI` client raises `requests.HTTPError` for a non-2xx response. Read the status with `err.response.status_code` and the body with `err.response.json()`. `raw=True` only changes successful return values. The serverless client also raises after its retries are used up. ## How Rate Limits Work From 337610fbff79a494e88252aba524535576be9175 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 01:25:50 -0700 Subject: [PATCH 203/250] docs(sla): address doc-review consensus (cycle 148) State that signed-in rate limits are per account, and stop listing examples from looking like live prices. Co-authored-by: Cursor --- .../openapi/yaml/create_instance.yaml | 2 +- api-reference/openapi/yaml/schedule_maint.yaml | 2 +- api-reference/openapi/yaml/search_offers.yaml | 2 +- api-reference/openapi/yaml/show_charges.yaml | 2 +- api-reference/openapi/yaml/show_earnings.yaml | 2 +- api-reference/openapi/yaml/show_instances.yaml | 2 +- api-reference/openapi/yaml/sla_backtest.yaml | 2 +- cli/rate-limits.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 8 ++++---- host/sla-offers.mdx | 18 +++++++++--------- sdk/python/rate-limits.mdx | 2 +- snippets/host/sdk/list-machine.mdx | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 59cc5baf..fbb01de3 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -300,7 +300,7 @@ x-rate-limit: threshold: 4.5 penalty: 12 per: request - description: Maximum request frequency per IP address for this endpoint + description: Rate limit per account for a signed-in API key. Unauthenticated calls are limited per IP address. x-input-validation: image: max_length: 1024 diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index 1af415f6..018f7778 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -128,7 +128,7 @@ components: x-rate-limit: threshold: 2.5 per: request - description: Maximum request frequency per IP address for this endpoint + description: Rate limit per account for a signed-in API key. Unauthenticated calls are limited per IP address. x-cli-commands: - name: schedule maint description: Schedule maintenance for a machine. diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index 0675b268..077c2881 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -467,4 +467,4 @@ x-tags: x-rate-limit: requests: 10 per: minute - description: Rate limit per IP address + description: Rate limit per account for a signed-in API key. Unauthenticated calls are limited per IP address. diff --git a/api-reference/openapi/yaml/show_charges.yaml b/api-reference/openapi/yaml/show_charges.yaml index 2ed1e471..1c9c55ca 100644 --- a/api-reference/openapi/yaml/show_charges.yaml +++ b/api-reference/openapi/yaml/show_charges.yaml @@ -261,7 +261,7 @@ components: x-rate-limit: threshold: 1.0 per: request - description: Maximum request frequency per IP address + description: Rate limit per account for a signed-in API key. Unauthenticated calls are limited per IP address. x-cli-commands: - name: show invoices-v1 diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index e164a391..a5762531 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -173,7 +173,7 @@ components: x-rate-limit: threshold: 2.0 per: request - description: Maximum request frequency per IP address for this endpoint + description: Rate limit per account for a signed-in API key. Unauthenticated calls are limited per IP address. x-cli-commands: - name: show earnings description: Retrieve earnings history for a specified time range and optionally diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index 56bea14f..c450f160 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -535,7 +535,7 @@ components: x-rate-limit: threshold: 1.0 per: request - description: Maximum request frequency per IP address for this endpoint + description: Rate limit per account for a signed-in API key. Unauthenticated calls are limited per IP address. x-cli-commands: - name: show instances-v1 description: Display user's current instances (paginated). diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index ce6c98fa..c4f4ce7b 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -253,4 +253,4 @@ components: x-rate-limit: threshold: 2.0 per: request - description: Maximum request frequency per IP address for this endpoint + description: Rate limit per account for a signed-in API key. Unauthenticated calls are limited per IP address. diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 0bda9393..7f7daf34 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -23,7 +23,7 @@ Some endpoints omit `success` or `error` and return only `msg` or `message`. The ## How Rate Limits Work -Vast.ai applies rate limits **per endpoint** and **per identity**. The identity is determined by your bearer token, session user, `api_key` parameter, and client IP. +Vast.ai applies rate limits **per endpoint**. For an API key, the limit is on that key's account. Extra keys on the same account share it. The client IP is used only when a request does not resolve to an account. Some endpoints also enforce **method-specific** limits (GET vs POST) and **max-calls-per-period** limits for short bursts. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 6f25f2f7..ab7465a8 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -36,7 +36,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. 2. In **Search filters** (left bar), set **Reliability target**. If that control is missing, SLA is not available in the console right now. Rent without it, or contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai. 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. -4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown, then click **RENT**. +4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. Write down **SLA Fee/hr**. You need it later to check credits, and the line is hidden while the instance is loading, stopped, or offline. Then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. 6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. A negative net is labeled **Service Credit**. Any other net is labeled **SLA Fee**. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). @@ -208,7 +208,7 @@ See the [Automation limits](#automation-limits) note in this section before you Web app: [cloud.vast.ai](https://cloud.vast.ai). REST examples use `https://console.vast.ai/api/…`. -For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, wait and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). +For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, read the JSON `error` field before you retry. `search_quota_exceeded` means wait until `Retry-After`, not a short backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. Rows from every query, including shards, count against one daily search row quota that varies by account. Size `limit` and the number of shards to fit that budget. See the **Daily search row quota** row below and [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -305,7 +305,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | -| Too many requests | HTTP 429. Detect throttling by the status code. The body differs by endpoint, so do not parse a `detail` field. Stay at or below about 10 search requests per minute per IP. If a `Retry-After` header is present, honor it. The CLI and SDK do not read that header. Space rent calls at least 5 seconds apart. A burst can block you for longer than that spacing. | Wait, then look up the same `label` with `GET /api/v1/instances/` before you retry. If a row exists, do not PUT again. If retry returns `invalid_price`, `no_such_ask`, or 410, re-search and rent a fresh offer id. | +| Too many requests | HTTP 429. The body varies by endpoint. Search can return `error: "search_quota_exceeded"` with `Retry-After`. | If `error` is `search_quota_exceeded`, stop until `Retry-After`. Otherwise wait and retry. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | | CLI or SDK retried a rent on its own | The CLI and SDK retry connection errors, timeouts, and HTTP 429, 502, 503, and 504. They do not read `Retry-After`. They cannot set `target_reliability`. | For an SLA rent you send yourself, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | | Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | @@ -456,7 +456,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. Compare it with **SLA Fee/hr** × the hours the contract was active that UTC day, including downtime. The Charges API returns the same net. Invoices do not. You cannot see the measured reliability for that day in the console or the API. +**Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. Compare it with the **SLA Fee/hr** you wrote down at rent (console quick start step 4) times the hours the contract was active that UTC day, including downtime. The Charges API returns the same net. Invoices do not. You cannot see the measured reliability for that day in the console or the API. **API integrators:** Use the same Charges row as [Settlement timing](#settlement-timing). The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. A row below the fee you expected means a credit was applied. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 8def96b5..6b1177fe 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -305,10 +305,10 @@ Some omitted fields reset to defaults (for example `price_disk`, `hidden_listing curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": 0.15, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": false, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": CURRENT_STORAGE_PRICE, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `price_disk` with the machine's current `listed_storage_cost`. Replace `CURRENT_MIN_CHUNK` with `listed_min_gpu_count` (it defaults to 1 only when offers are created or re-created). Send `"hidden_listing": true` if the listing is hidden. Do not copy example prices into a first listing. Send `end_date` only in the full listing update below, when you mean to extend. +Replace every `CURRENT_*` value from `vastai show machines --raw`: `listed_storage_cost`, `listed_min_gpu_count`, and whether the listing is hidden. An unedited paste is not valid JSON. `min_chunk` defaults to 1 only when offers are created or re-created. Send `end_date` only in the full listing update below, when you mean to extend. Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes Claim or Confidence in a way that would raise that contract's SLA fee. A Claim or Confidence change does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). @@ -324,11 +324,11 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Content-Type: application/json" \ -d '{ "machine": 12345, - "price_gpu": 3.50, - "price_disk": 0.15, + "price_gpu": CURRENT_GPU_PRICE, + "price_disk": CURRENT_STORAGE_PRICE, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, - "hidden_listing": false, + "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5, "end_date": CURRENT_END_DATE_UNIX @@ -348,11 +348,11 @@ SLA fields example (existing listing, no extension). Same fields as the curl abo ```json { "machine": 12345, - "price_gpu": 3.50, - "price_disk": 0.15, + "price_gpu": CURRENT_GPU_PRICE, + "price_disk": CURRENT_STORAGE_PRICE, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, - "hidden_listing": false, + "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5 } @@ -403,7 +403,7 @@ Use this loop only to restore SLA offers that no longer appear in search on mach Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. You cannot see per-contract end dates beforehand. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). -The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute per IP. The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. +The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute for the account, not for each API key. See [How rate limits are applied](/api-reference/rate-limits-and-errors#how-rate-limits-are-applied). The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. `show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, omitting it keeps the current confidence. If the PUT creates a **new** ask, the server sets `sla_sigma_x` to `0.5` unless you send it. Keep your own record of each machine's σ and check **Set Pricing → SLA** after any run that logs a new ask. diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index b2e9cd93..112d941c 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -25,7 +25,7 @@ After its built-in retries are used up, the `VastAI` client raises `requests.HTT ## How Rate Limits Work -Vast.ai applies rate limits **per endpoint** and **per identity**. The identity is determined by your bearer token, session user, `api_key` parameter, and client IP. +Vast.ai applies rate limits **per endpoint**. For an API key, the limit is on that key's account. Extra keys on the same account share it. The client IP is used only when a request does not resolve to an account. Some endpoints also enforce **method-specific** limits (GET vs POST) and **max-calls-per-period** limits for short bursts. diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index dec203a0..aea78ea9 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -85,9 +85,9 @@ VastAI.list_machine( from vastai import VastAI client = VastAI(api_key="YOUR_API_KEY") -# Replace price_disk and min_chunk with this machine's current values. +# Replace CURRENT_* from vastai show machines --raw. An unedited paste should fail. # Reprice without extending rentals. Do not pass end_date unless you mean to extend. # Pass duration again only if this listing auto-renews. -result = client.list_machine(id=12345, price_gpu=3.50, price_disk=0.15, min_chunk=1, vol_size=0) +result = client.list_machine(id=12345, price_gpu=CURRENT_GPU_PRICE, price_disk=CURRENT_STORAGE_PRICE, min_chunk=CURRENT_MIN_CHUNK, vol_size=0) print(result) ``` From 8f2e8d7c8bdadb88eccbb4b358f01757c1941636 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 01:54:36 -0700 Subject: [PATCH 204/250] docs(sla): address doc-review consensus (cycle 149) Stop documenting a filter the server rejects, and describe Charges settlement and 429 bodies as they actually return. Co-authored-by: Cursor --- api-reference/openapi.yaml | 22 +++++++-------- .../openapi/yaml/create_instance.yaml | 2 +- .../openapi/yaml/schedule_maint.yaml | 2 +- api-reference/openapi/yaml/show_charges.yaml | 2 +- api-reference/openapi/yaml/show_earnings.yaml | 2 +- .../openapi/yaml/show_instances.yaml | 6 ++--- api-reference/permissions.mdx | 4 +-- api-reference/rate-limits-and-errors.mdx | 27 +++++++++++-------- guides/instances/choosing/sla-coverage.mdx | 22 ++++++++++++--- host/sla-offers.mdx | 6 ++--- snippets/host/cli/schedule-maint.mdx | 6 ++--- 11 files changed, 60 insertions(+), 41 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index e11db514..1f217891 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1897,7 +1897,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=4.5 + example: 'API requests too frequent: endpoint threshold=4.5*1' operationId: createInstance /api/v0/ssh: post: @@ -6503,7 +6503,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=2.5 + example: 'API requests too frequent: endpoint threshold=2.5*1' tags: - Machines operationId: scheduleMaint @@ -7613,7 +7613,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=1.0 + example: 'API requests too frequent: endpoint threshold=1.0*1' tags: - Billing operationId: showCharges @@ -8116,7 +8116,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=2.0 + example: 'API requests too frequent: endpoint threshold=2.0*1' tags: - Billing operationId: showEarnings @@ -8179,13 +8179,13 @@ paths: Filterable columns: `actual_status`, `gpu_name`, `verification`, `id`, `label`, and other columns stored directly on the contract record - (including `sla_r_claim` and `sla_r_target` / `target_reliability` when - present). Computed fields (e.g. `dph_total`, `num_gpus`, `has_sla`) are - not filterable and return 400. + (including `sla_r_claim` and `sla_r_target` when present). `target_reliability` + is a response field only; sending it as a filter key returns an error. Computed + fields (e.g. `dph_total`, `num_gpus`, `has_sla`) are not filterable and + return 400. - Prefer client-side filtering on `target_reliability > 0` for SLA-covered - instances. Optional `select_filters` on stored SLA fields may work for some - keys; do not rely on it as the only detection path. + To find SLA rentals, filter on `sla_r_target` or filter client-side on `target_reliability + > 0`. ' schema: @@ -8693,7 +8693,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=1.0 + example: 'API requests too frequent: endpoint threshold=1.0*1' tags: - Instances operationId: showInstances diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index fbb01de3..de30173c 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -277,7 +277,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=4.5 + example: "API requests too frequent: endpoint threshold=4.5*1" components: securitySchemes: ApiKeyAuth: diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index 018f7778..4997c43c 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -105,7 +105,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=2.5 + example: "API requests too frequent: endpoint threshold=2.5*1" tags: - Machines components: diff --git a/api-reference/openapi/yaml/show_charges.yaml b/api-reference/openapi/yaml/show_charges.yaml index 1c9c55ca..61b5cbd6 100644 --- a/api-reference/openapi/yaml/show_charges.yaml +++ b/api-reference/openapi/yaml/show_charges.yaml @@ -232,7 +232,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=1.0 + example: "API requests too frequent: endpoint threshold=1.0*1" tags: - Billing diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index a5762531..149d5da9 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -152,7 +152,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=2.0 + example: "API requests too frequent: endpoint threshold=2.0*1" tags: - Billing components: diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index c450f160..49bf35c9 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -54,8 +54,8 @@ paths: description: | JSON object of column filters. Supported operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `notin`. Filterable columns: `actual_status`, `gpu_name`, `verification`, `id`, `label`, and other columns stored directly on the contract record - (including `sla_r_claim` and `sla_r_target` / `target_reliability` when present). Computed fields (e.g. `dph_total`, `num_gpus`, `has_sla`) are not filterable and return 400. - Prefer client-side filtering on `target_reliability > 0` for SLA-covered instances. Optional `select_filters` on stored SLA fields may work for some keys; do not rely on it as the only detection path. + (including `sla_r_claim` and `sla_r_target` when present). `target_reliability` is a response field only; sending it as a filter key returns an error. Computed fields (e.g. `dph_total`, `num_gpus`, `has_sla`) are not filterable and return 400. + To find SLA rentals, filter on `sla_r_target` or filter client-side on `target_reliability > 0`. schema: type: string default: '{}' @@ -512,7 +512,7 @@ paths: properties: detail: type: string - example: API requests too frequent endpoint threshold=1.0 + example: "API requests too frequent: endpoint threshold=1.0*1" tags: - Instances components: diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 7b103382..bd6dda5f 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -121,7 +121,7 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if | Rent with an SLA | `instance_write` | Console **RENT** | | Verify `target_reliability` | `instance_read` | **Instances** | -**Service credits:** **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net row. How that row is labeled is in [Settlement timing](/guides/instances/choosing/sla-coverage#settlement-timing). The call requires `select_filters` with both `day.gte` and `day.lte` (unix seconds, UTC). A call without that range returns HTTP 400. The row is omitted until the last day in the window has settled. Page by sending `next_token` as `after_token`. Stop when `next_token` is `null`. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. +**Service credits:** **Account → Billing → Charges** and `GET /api/v0/charges/` show the same net row. How that row is labeled is in [Settlement timing](/guides/instances/choosing/sla-coverage#settlement-timing). The call requires `select_filters` with both `day.gte` and `day.lte` (unix seconds, UTC). A call without that range returns HTTP 400. The contract row can appear before settlement. Its `type: "sla"` item is absent until that day settles. Page by sending `next_token` as `after_token`. Stop when `next_token` is `null`. Invoices (`GET /api/v1/invoices/`) are payment transactions, not SLA credits. ```bash curl -G "https://console.vast.ai/api/v0/charges/" \ @@ -130,7 +130,7 @@ curl -G "https://console.vast.ai/api/v0/charges/" \ ``` -Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). An amount smaller than the SLA fee you expected, or a negative amount, means a credit was applied. The row is missing until that day has settled. +Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). An amount smaller than the SLA fee you expected, or a negative amount, means a credit was applied. The contract row can appear before settlement. Its `sla` item is absent until that day settles. diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index d863ef3b..5b9e8ad2 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -29,22 +29,27 @@ For a signed-in API key, the limit is per user account. Extra keys on the same a Some endpoints also use **method-specific** limits (GET vs POST) and/or **max-calls-per-period** limits for short bursts. +The combined API reference does not always show each operation's `x-rate-limit` block. For SLA workflows, use this pacing: + +| Endpoint | Safe pacing | +| --- | --- | +| Search offers (`POST /bundles/`) | about 10 requests per minute | +| Rent (`PUT /asks/{id}/`) | one call every 4.5 seconds or slower | +| Show instances (v1) | one call per second | +| Show charges | one call per second | +| Show earnings and the SLA backtester | one call every 2 seconds | +| Schedule maintenance | one call every 2.5 seconds | +| Create or update a listing (`create_asks`) | one call every 5 seconds | ### Rate limit response behavior -When you hit a rate limit, you will receive **HTTP 429**. The response body is often plain text (in certain cases JSON with `success`/`error`/`msg` like above) with one of the following messages: +When you hit a rate limit, you will receive **HTTP 429**. The body is one of three shapes: -``` -API requests too frequent -``` - -or - -``` -API requests too frequent: endpoint threshold=... -``` +- Plain text: `API requests too frequent: endpoint threshold=…` +- JSON with a `detail` key containing that same message +- Search quota only: JSON `{"error": "search_quota_exceeded", "msg": "…"}` plus a `Retry-After` header -Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value points at the quota reset, which can be hours away. When `Retry-After` is present, wait at least that long. When it is absent, use your own backoff. +Treat any other 429 as a short backoff. Only `search_quota_exceeded` carries `Retry-After`, and that wait can be hours. ### How to reduce rate limit errors diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index ab7465a8..3725c458 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -208,7 +208,7 @@ See the [Automation limits](#automation-limits) note in this section before you Web app: [cloud.vast.ai](https://cloud.vast.ai). REST examples use `https://console.vast.ai/api/…`. -For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, read the JSON `error` field before you retry. `search_quota_exceeded` means wait until `Retry-After`, not a short backoff. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). +For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, if the JSON `error` is `search_quota_exceeded`, wait for `Retry-After`. Otherwise (a `detail` body or plain text), back off before the next call. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. Rows from every query, including shards, count against one daily search row quota that varies by account. Size `limit` and the number of shards to fit that budget. See the **Daily search row quota** row below and [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -292,7 +292,21 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. -**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Each Charges row is one contract. Match `source` to `instance-` plus the contract ID from `new_contract` (or `metadata.label` if you set a unique label at rent), then read the `sla` item in `items[]`. Store the hourly SLA fee when the rent succeeds: `search.slaPremiumPerHour` on the `GET /api/v1/instances/` row for that contract. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. Expected fee for a UTC day is about the stored rate times the hours the contract was active, including downtime. A `sla` row smaller than that, or negative, means a credit was applied. How the console labels that row is in [Settlement timing](#settlement-timing). The call requires `select_filters` with `day.gte` and `day.lte` (unix seconds). The row is omitted until the last day in the window has settled, so a window that includes the current UTC day has no SLA row yet. Each `items[]` entry is the total for that charge type over the whole query window. To see one UTC day, set `day.gte` to that day's start and `day.lte` to `day.gte + 86399`. Page with `after_token` / `next_token` (`limit` defaults to 100, maximum 500) and space calls about one second apart. Send the response `next_token` as `after_token`. Stop when `next_token` is `null`. Compare the row with the SLA fee you expected: a smaller or negative amount means a credit was applied. +**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Store the hourly SLA fee when the rent succeeds: `search.slaPremiumPerHour` on the `GET /api/v1/instances/` row for that contract. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. + +1. Call Show Charges for one UTC day. `day.gte` and `day.lte` are both required (unix seconds). Set `day.lte` to `day.gte + 86399`. +2. Page with `after_token` / `next_token` until `next_token` is `null`. Space calls about one second apart. +3. Find the row whose `source` is `instance-` plus the contract id from `new_contract`, then the `items[]` entry with `type: "sla"`. +4. Compare that amount with the stored hourly fee times the hours the contract was active that day, including downtime. A smaller or negative amount means a credit was applied. How the console labels the row is in [Settlement timing](#settlement-timing). + +The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. + +```bash +curl -s -G "https://console.vast.ai/api/v0/charges/" \ + -H "Authorization: Bearer $VAST_API_KEY" \ + --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1767311999}}' \ + | jq --arg s "instance-$NEW_CONTRACT" '.results[] | select(.source == $s) | .items[] | select(.type == "sla") | .amount' +``` **Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read Charges after settlement (see [Settlement timing](#settlement-timing)). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). @@ -342,7 +356,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. -**Stop vs destroy:** While an SLA instance is unavailable, you are billed for GPU compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. **Destroy** the instance when you are done. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. +**Stop vs destroy:** While an SLA instance is unavailable, you are billed for GPU compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. Until that rule is published, budget as if a stopped SLA instance is still billed for both. Only **Destroy** is documented to end those charges, and it deletes the disk. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. @@ -415,7 +429,7 @@ Console users: open **Instances** → select your instance → **price details** Show-instances output may include `target_reliability` and price fields under `search` / `instance` (including `slaPremiumPerHour`). -To find instances with an SLA, post-process the API response in your application (filter or paginate locally)—not in the Vast web console. Prefer filtering the show-instances response (`target_reliability > 0`, `instance.slaPremiumPerHour`) in production. OpenAPI documents optional `select_filters` on stored fields such as `sla_r_target` / `target_reliability` when present; computed fields (for example `has_sla`) are not filterable. Do not rely on `select_filters` alone to detect an SLA. +To find instances with an SLA, post-process the API response in your application (filter or paginate locally)—not in the Vast web console. Prefer filtering the show-instances response on `target_reliability > 0`. `select_filters` accepts `sla_r_target` (the stored reliability target). `target_reliability` is a response field only; sending it as a filter key returns an error (`target_reliability is not a valid search key`). Computed fields (for example `has_sla`) are not filterable. **You set at search/rent** diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 6b1177fe..9c602401 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -151,7 +151,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | | Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.99999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | -| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | How wide your belief is around the reliability commitment. Lower = more confident (lower SLA fees for clients at a given target). Defaults to `0.5` only on a **new** ask. When you first enable SLA on an existing listing, send `sla_sigma_x` yourself. Omitting it leaves the stored value empty, so `show machines` reports no confidence. On an ask that already has a stored value, omitting `sla_sigma_x` keeps that value. | +| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | Pricing margin built into the SLA fee. Tight is a smaller fee. Wide is a larger fee. It does not change the credit you owe. Defaults to `0.5` only on a **new** ask. When you first enable SLA on an existing listing, send `sla_sigma_x` yourself. Omitting it leaves the stored value empty, so `show machines` reports no confidence. On an ask that already has a stored value, omitting `sla_sigma_x` keeps that value. | ### Advanced: `sla_max_beta` (optional) @@ -186,7 +186,7 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r ### Confidence values -In the console, pick **Tight**, **Normal**, or **Wide**. You do not need the table unless you use the API or the backtester. +In the console, pick **Tight**, **Normal**, or **Wide**. You do not need the table unless you use the API or the backtester. In `show machines`, `high` means Tight and `low` means Wide. A `low` label is a deliberate wide margin, not a weak setting. | Console label | API `sla_sigma_x` (σ) | Backtester `p` | `show machines` | Pricing effect | | --- | --- | --- | --- | --- | @@ -772,7 +772,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Keep your own record of the exact `sla_sigma_x`.** `show machines` returns only the confidence band. It does return `credit_discount_max` while the machine is listed (`null` after unlist) and `min_bid_price` (your host-side minimum bid, net of the platform fee). The read-back can differ slightly from what you sent, so resend the `price_min_bid` you wrote down. Omitting it keeps the stored minimum. An offline machine drops out of `show machines` after about 10 hours (about 3 days with `include_offline=true`). Snapshot before you unlist. - 1. **Notify renters.** `echo y | vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration HOURS --maintenance_category other`. See [Set a maintenance window](/host/set-maintenance-window). + 1. **Notify renters.** `echo y | vastai schedule maint MACHINE_ID --sdate "$(( $(date -u +%s) + 60 ))" --duration HOURS --maintenance_category other`. One minute ahead still counts as an unplanned window. See [Set a maintenance window](/host/set-maintenance-window). 2. **Get your current terms before you unlist.** If the machine is still visible, save them now. If it is not, use your own notes. After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, `credit_discount_max`, and SLA terms. The snapshot also omits hidden status (`hidden_listing`) and the exact `sla_sigma_x`. Write those down too. **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, Confidence (Tight, Normal, or Wide), the reserved discount, and the interruptible min bid. An omitted reserved discount on a new ask becomes `0.4`. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 6f15f3e8..7143c1ea 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -21,7 +21,7 @@ vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_ca ## Options - Maintenance start time as Unix epoch seconds (UTC). Required. Use a future time, as far ahead as you can, for example `$(date -u -d '2 days 02:00:00' +%s)`. The CLI sends this value to the API unchanged (REST `sdate` is also epoch seconds). + Maintenance start time as Unix epoch seconds (UTC). Required. For planned work, use a future time, as far ahead as you can. For an outage already underway, one minute from now is enough. This single-machine route accepts the current time. @@ -59,10 +59,10 @@ vastai schedule maint MACHINE_ID \ ### Emergency or unplanned maintenance -If the machine must go offline without adequate notice, still run `schedule maint` to notify renters — but expect the full service-credit amount that can be owed when SLA is enabled. Use the current UTC epoch for `--sdate` and an integer `--duration` (hours): +If the machine must go offline without adequate notice, still run `schedule maint` to notify renters — but expect the full service-credit amount that can be owed when SLA is enabled. Start one minute from now so the window is still ahead of the confirmation prompt: ```bash -vastai schedule maint MACHINE_ID --sdate "$(date -u +%s)" --duration 1 --maintenance_category power +vastai schedule maint MACHINE_ID --sdate "$(( $(date -u +%s) + 60 ))" --duration 1 --maintenance_category power ``` To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine, and it asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID` and confirm the cancel succeeded before you recreate windows. To reschedule, cancel first, then recreate each window you still want, as far ahead as you can. Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. From 6ed2527e16b625296b6e11c8a2a1ae2230f5a936 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 02:06:11 -0700 Subject: [PATCH 205/250] docs(sla): address doc-review consensus (cycle 150) Describe the two HTTP 429 families the server actually returns, and page Charges before treating a missing SLA item as unsettled. Co-authored-by: Cursor --- api-reference/openapi.yaml | 10 ++++++++-- api-reference/openapi/yaml/create_instance.yaml | 1 - api-reference/openapi/yaml/show_charges.yaml | 10 ++++++++-- api-reference/permissions.mdx | 9 +++++---- api-reference/rate-limits-and-errors.mdx | 11 +++++------ cli/rate-limits.mdx | 17 +++++------------ guides/instances/choosing/sla-coverage.mdx | 10 ++++++---- guides/reference/billing.mdx | 2 +- host/sla-offers.mdx | 8 ++++---- sdk/python/rate-limits.mdx | 17 +++++------------ 10 files changed, 47 insertions(+), 48 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 1f217891..3dfca0ac 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -7611,9 +7611,15 @@ paths: schema: type: object properties: - detail: + error: type: string - example: 'API requests too frequent: endpoint threshold=1.0*1' + example: HTTPTooManyRequests + msg: + type: string + example: API requests too frequent + retry_after: + type: integer + example: 1 tags: - Billing operationId: showCharges diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index de30173c..5c90783a 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -298,7 +298,6 @@ components: type: string x-rate-limit: threshold: 4.5 - penalty: 12 per: request description: Rate limit per account for a signed-in API key. Unauthenticated calls are limited per IP address. x-input-validation: diff --git a/api-reference/openapi/yaml/show_charges.yaml b/api-reference/openapi/yaml/show_charges.yaml index 61b5cbd6..470f8c0e 100644 --- a/api-reference/openapi/yaml/show_charges.yaml +++ b/api-reference/openapi/yaml/show_charges.yaml @@ -230,9 +230,15 @@ paths: schema: type: object properties: - detail: + error: type: string - example: "API requests too frequent: endpoint threshold=1.0*1" + example: HTTPTooManyRequests + msg: + type: string + example: API requests too frequent + retry_after: + type: integer + example: 1 tags: - Billing diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index bd6dda5f..427da4d2 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -12,7 +12,7 @@ Use this page for scoped API keys and automation. If you only use the web consol | If you are… | Start here | API key needed? | | --- | --- | --- | | Renter (console) | [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console) | No | -| Host (console) | [SLA Offers](/host/sla-offers#web-console) | No | +| Host (console) | [SLA Offers](/host/sla-offers#web-console) | No for listing. Per-machine SLA earnings need the CLI and a `billing_read` key. | | Automating search, rent, or listing | Continue below ([renter recipe](#renter-sla-scoped-key-recipe) · [host recipe](#host-sla-scoped-key-recipe)) | Yes | On this page, **renter** means client and **host** means provider. API names may still say client or provider. @@ -97,7 +97,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do **Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. Charges and **Account → Billing → Charges** show the same net `type: "sla"` row. The console labels it **Service Credit** only when the amount is negative. -- Create a **dedicated** key for this workflow only. `misc` covers bundle search and other bundled routes—not only search (including serverless). Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. +- Create a **dedicated** key for this workflow only. `misc` covers offer search **and** unrelated routes such as serverless endpoints and workergroups. Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. - **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances --raw` (that command already calls v1). Store `search.slaPremiumPerHour` from the instance row when the rent succeeds. `instance.slaPremiumPerHour` is a cross-check only while the instance is running. It reads `0` while loading, stopped, or offline. @@ -126,11 +126,12 @@ This is the minimum for search, REST rent, and verification. Add `user_read` if ```bash curl -G "https://console.vast.ai/api/v0/charges/" \ -H "Authorization: Bearer $VAST_API_KEY" \ - --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1767311999}}' + --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1767311999}}' \ + --data-urlencode "limit=500" ``` -Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). An amount smaller than the SLA fee you expected, or a negative amount, means a credit was applied. The contract row can appear before settlement. Its `sla` item is absent until that day settles. +Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). An amount smaller than the SLA fee you expected, or a negative amount, means a credit was applied. The contract row can appear before settlement. Its `sla` item is absent until that day settles. If `next_token` is not `null`, repeat the request with `after_token` before you treat a missing `sla` item as unsettled. diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index 5b9e8ad2..bbf83e1f 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -34,7 +34,7 @@ The combined API reference does not always show each operation's `x-rate-limit` | Endpoint | Safe pacing | | --- | --- | | Search offers (`POST /bundles/`) | about 10 requests per minute | -| Rent (`PUT /asks/{id}/`) | one call every 4.5 seconds or slower | +| Rent (`PUT /asks/{id}/`) | one call every 4.5 seconds; space calls at least 5 seconds apart | | Show instances (v1) | one call per second | | Show charges | one call per second | | Show earnings and the SLA backtester | one call every 2 seconds | @@ -43,13 +43,12 @@ The combined API reference does not always show each operation's `x-rate-limit` ### Rate limit response behavior -When you hit a rate limit, you will receive **HTTP 429**. The body is one of three shapes: +When you hit a rate limit, you will receive **HTTP 429**. There are two families: -- Plain text: `API requests too frequent: endpoint threshold=…` -- JSON with a `detail` key containing that same message -- Search quota only: JSON `{"error": "search_quota_exceeded", "msg": "…"}` plus a `Retry-After` header +- **Legacy endpoints** (rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`): a plain-text body such as `API requests too frequent: endpoint threshold=…`, with no `Retry-After` header. +- **Token-bucket endpoints** (search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`): JSON `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}` with a short `Retry-After` header. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. -Treat any other 429 as a short backoff. Only `search_quota_exceeded` carries `Retry-After`, and that wait can be hours. +Honor `Retry-After` whenever it is present. If it is absent, back off yourself. ### How to reduce rate limit errors diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 7f7daf34..f6e302df 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -31,19 +31,12 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li ## Rate Limit Response -When you hit a rate limit, the API returns **HTTP 429** with a message like: +HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -``` -API requests too frequent -``` - -or - -``` -API requests too frequent: endpoint threshold=... -``` +- Legacy rent and show-instances calls return plain text and no `Retry-After`. +- Search and charges return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. -Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. The CLI never reads that header. With the default of 3 attempts, those retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. +The CLI never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. ## Built-in Retry Behavior @@ -62,7 +55,7 @@ The CLI retries 429, 502, 503, 504, connection errors, and timeouts. Other HTTP ## Configuring Retries -Use the `--retry` flag on any command to change the number of retry attempts: +Use the `--retry` flag on any command to change the total number of attempts: ```bash # Default: 3 attempts diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 3725c458..92f5c9b8 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -76,6 +76,7 @@ SLA is a **contractual, per-rental** reliability guarantee with automatic daily For on-demand contracts with an SLA: +- An SLA pays a **service credit**. It does not recover your data, migrate your instance, or replace the machine. Keep checkpoints and important data off the instance. - You are charged for **compute, storage, and the SLA fee** for the rental day, including periods when the instance is unavailable. - Offline time is tracked as an outage in reliability measurements. - If you qualify for compensation, a **service credit** posts after daily settlement (UTC) — typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. @@ -208,7 +209,7 @@ See the [Automation limits](#automation-limits) note in this section before you Web app: [cloud.vast.ai](https://cloud.vast.ai). REST examples use `https://console.vast.ai/api/…`. -For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, if the JSON `error` is `search_quota_exceeded`, wait for `Retry-After`. Otherwise (a `detail` body or plain text), back off before the next call. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). +For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, if `error` is `search_quota_exceeded`, wait for `Retry-After` (it can be hours). A shorter search limit returns `"error": "HTTPTooManyRequests"` and a short `Retry-After`. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). **1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. Rows from every query, including shards, count against one daily search row quota that varies by account. Size `limit` and the number of shards to fit that budget. See the **Daily search row quota** row below and [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -299,12 +300,13 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta 3. Find the row whose `source` is `instance-` plus the contract id from `new_contract`, then the `items[]` entry with `type: "sla"`. 4. Compare that amount with the stored hourly fee times the hours the contract was active that day, including downtime. A smaller or negative amount means a credit was applied. How the console labels the row is in [Settlement timing](#settlement-timing). -The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. +The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. If `next_token` is not `null`, repeat the request with `after_token` set to that value before you treat a missing `sla` item as unsettled. `limit` defaults to 100, so a busy account can put the contract on a later page. ```bash curl -s -G "https://console.vast.ai/api/v0/charges/" \ -H "Authorization: Bearer $VAST_API_KEY" \ --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1767311999}}' \ + --data-urlencode "limit=500" \ | jq --arg s "instance-$NEW_CONTRACT" '.results[] | select(.source == $s) | .items[] | select(.type == "sla") | .amount' ``` @@ -319,7 +321,7 @@ curl -s -G "https://console.vast.ai/api/v0/charges/" \ | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | -| Too many requests | HTTP 429. The body varies by endpoint. Search can return `error: "search_quota_exceeded"` with `Retry-After`. | If `error` is `search_quota_exceeded`, stop until `Retry-After`. Otherwise wait and retry. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | +| Too many requests | HTTP 429. Search returns JSON. `error` is `HTTPTooManyRequests` for a short limit, or `search_quota_exceeded` when the daily row quota is used up. | If `error` is `search_quota_exceeded`, stop until `Retry-After` (it can be hours). Otherwise honor the short `Retry-After`. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. Rent 429s are plain text and have no `Retry-After`. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | | CLI or SDK retried a rent on its own | The CLI and SDK retry connection errors, timeouts, and HTTP 429, 502, 503, and 504. They do not read `Retry-After`. They cannot set `target_reliability`. | For an SLA rent you send yourself, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | | Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | @@ -356,7 +358,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. -**Stop vs destroy:** While an SLA instance is unavailable, you are billed for GPU compute, storage, and the SLA fee until you **Destroy**. Destroy deletes the disk. **Stop** is not guaranteed to end the GPU charge or the SLA fee. Until that rule is published, budget as if a stopped SLA instance is still billed for both. Only **Destroy** is documented to end those charges, and it deletes the disk. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. +**Stop vs destroy.** Vast has not published whether **Stop** ends GPU or SLA charges on an SLA rental. Budget as if a stopped SLA instance is still billed for GPU, storage, and the SLA fee. Only **Destroy** is documented to end those charges, and it deletes the disk. If your balance reaches $0 and you have no saved card, a stopped SLA instance can keep the balance negative while its data is scheduled for deletion. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index ece71dbc..72866781 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -16,7 +16,7 @@ We accept credit card payments through Stripe and crypto payments through BitPay ### Negative Balances -Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. +Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. On an SLA rental, **Stop** is not documented to end GPU or SLA charges. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). **When your balance reaches zero (or below):** - Your instances are **stopped automatically**. If you rent with an SLA, a stop at zero balance is not guaranteed to end the GPU charge or the SLA fee. Top up, or **Destroy** the instance if you need those charges to stop. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 9c602401..bab87d2e 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -308,7 +308,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{"machine": 12345, "price_disk": CURRENT_STORAGE_PRICE, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace every `CURRENT_*` value from `vastai show machines --raw`: `listed_storage_cost`, `listed_min_gpu_count`, and whether the listing is hidden. An unedited paste is not valid JSON. `min_chunk` defaults to 1 only when offers are created or re-created. Send `end_date` only in the full listing update below, when you mean to extend. +Replace every `CURRENT_*` value from `vastai show machines --raw`: `listed_storage_cost`, `listed_min_gpu_count`, and whether the listing is hidden. An unedited paste is not valid JSON. `min_chunk` defaults to 1 only when offers are created or re-created. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Re-send bandwidth prices, `credit_discount_max`, `price_min_bid`, and `sla_sigma_x` right away, or the new ask keeps the defaults (bandwidth `0`, discount `0.4`, confidence `0.5`). Send `end_date` only in the full listing update below, when you mean to extend. Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes Claim or Confidence in a way that would raise that contract's SLA fee. A Claim or Confidence change does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). @@ -807,7 +807,7 @@ After you enable SLA, charges and credits settle on UTC (Coordinated Universal T 1. Go to **Host → Billing**. 2. Set the date range to include the UTC day you want to review. -3. Machine filtering is not available in the console. For one machine, use `vastai show earnings --machine_id ID`. +3. Machine filtering is not available in the console. Per-machine SLA amounts need the CLI and an API key with `billing_read` (`vastai show earnings --machine_id ID`). See [API keys for SLA](/api-reference/permissions). 4. SLA fees you keep and credits you owe are folded into the daily earnings total. There is no separate SLA line. Compare the total with a normal week. For one machine's SLA amount, run `vastai show earnings --machine_id ID` and read `sla_earn`. 5. After downtime, compare several days with a normal week. Much of the escrow can stay held until the contract ends, so a low `sla_earn` is not by itself a credit. Do not look for a negative SLA line, and do not match one day to the backtester's largest single-day credit. @@ -846,7 +846,7 @@ Weekly aggregates are window totals, not daily series — use a one-day range ab ### API (automation) -**Console users:** Skip this section for fleet-wide totals in **Host → Billing**. To see SLA results for one machine, use `vastai show earnings --machine_id ID` with an API key that has `billing_read`. +**Console users:** Skip this section. **Host → Billing** shows fleet-wide totals. For one machine's SLA amount, run `vastai show earnings --machine_id ID` with a `billing_read` key. **API keys for SLA** @@ -873,7 +873,7 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Pull several hours after UTC midnight (for example 06:00 UTC). Later corrections can change `sla_earn`, so re-pull a trailing window (`sday` six days earlier through yesterday) instead of recording a day once. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. - **Fleet, exact UTC day (one call):** omit `machid` and set `sday` and `eday` to the same day index. Read `per_machine[].sla_earn`. - **Recent window (`last_days`, coarse):** one request without `machid` returns all machines in `per_machine[]`. `last_days=1` spans yesterday and today-so-far. diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 112d941c..251d1bc4 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -33,19 +33,12 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li ## Rate Limit Response -When you hit a rate limit, the API returns **HTTP 429** with a message like: +HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -``` -API requests too frequent -``` - -or - -``` -API requests too frequent: endpoint threshold=... -``` +- Legacy rent and show-instances calls return plain text and no `Retry-After`. +- Search and charges return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. -Some HTTP 429 responses include a `Retry-After` header. The daily search row quota (`error: "search_quota_exceeded"`) does, and its value can be hours. The SDK never reads that header. With the default of 3 attempts, those retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. +The SDK never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. ## Built-in Retry Behavior @@ -89,7 +82,7 @@ The serverless client retries on a wider range of errors than the `VastAI` clien ### VastAI Client -Pass the `retry` parameter to the constructor to change the number of retry attempts: +Pass the `retry` parameter to the constructor to change the total number of attempts: ```python from vastai import VastAI From d4ffcc5ec9537550943977650b64fe51d8a6fedb Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 02:14:52 -0700 Subject: [PATCH 206/250] docs(sla): address doc-review consensus (cycle 151) Keep hidden listings from being read off show machines, and match each 429 example to the limiter that actually sends it. Co-authored-by: Cursor --- api-reference/openapi.yaml | 73 +++++++++++++------ .../openapi/yaml/create_instance.yaml | 11 +-- .../openapi/yaml/schedule_maint.yaml | 17 ++++- api-reference/openapi/yaml/search_offers.yaml | 5 +- api-reference/openapi/yaml/show_charges.yaml | 7 +- api-reference/openapi/yaml/show_earnings.yaml | 17 ++++- .../openapi/yaml/show_instances.yaml | 11 +-- api-reference/permissions.mdx | 4 +- api-reference/rate-limits-and-errors.mdx | 8 +- cli/rate-limits.mdx | 4 +- cli/reference/create-instance.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 8 +- guides/reference/billing.mdx | 2 +- host/sla-offers.mdx | 4 +- sdk/python/rate-limits.mdx | 4 +- sdk/python/reference/create-instance.mdx | 2 +- 16 files changed, 113 insertions(+), 66 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 3dfca0ac..4801678a 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1889,15 +1889,13 @@ paths: type: integer example: 1234567 '429': - description: Too Many Requests + description: Too Many Requests. Legacy limiter. Plain-text body, no Retry-After + header. `penalty` is not applied on this route. content: - application/json: + text/plain: schema: - type: object - properties: - detail: - type: string - example: 'API requests too frequent: endpoint threshold=4.5*1' + type: string + example: 'API requests too frequent: endpoint threshold=4.5*1' operationId: createInstance /api/v0/ssh: post: @@ -6495,15 +6493,26 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests + description: Too Many Requests. JSON body and a Retry-After header. + headers: + Retry-After: + schema: + type: integer + description: Seconds to wait. content: application/json: schema: type: object properties: - detail: + error: + type: string + example: HTTPTooManyRequests + msg: type: string - example: 'API requests too frequent: endpoint threshold=2.5*1' + example: API requests too frequent + retry_after: + type: integer + example: 3 tags: - Machines operationId: scheduleMaint @@ -7076,15 +7085,17 @@ paths: '429': description: 'Too many requests, or the daily search row quota is exhausted. - `error: search_quota_exceeded` includes a `Retry-After` header (seconds - until the quota resets, which can be hours). + Both `HTTPTooManyRequests` and `search_quota_exceeded` include a `Retry-After` + header. + + The quota error''s wait can be hours. ' headers: Retry-After: schema: type: integer - description: Seconds to wait. Present on `search_quota_exceeded`. + description: Seconds to wait. Present on both search 429s. content: application/json: schema: @@ -7605,7 +7616,12 @@ paths: error: auth_error msg: Invalid user key '429': - description: Too Many Requests + description: Too Many Requests. JSON body and a Retry-After header. + headers: + Retry-After: + schema: + type: integer + description: Seconds to wait. content: application/json: schema: @@ -8114,15 +8130,26 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests + description: Too Many Requests. JSON body and a Retry-After header. + headers: + Retry-After: + schema: + type: integer + description: Seconds to wait. content: application/json: schema: type: object properties: - detail: + error: + type: string + example: HTTPTooManyRequests + msg: type: string - example: 'API requests too frequent: endpoint threshold=2.0*1' + example: API requests too frequent + retry_after: + type: integer + example: 2 tags: - Billing operationId: showEarnings @@ -8691,15 +8718,13 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests + description: Too Many Requests. Legacy limiter. Plain-text body, no Retry-After + header. content: - application/json: + text/plain: schema: - type: object - properties: - detail: - type: string - example: 'API requests too frequent: endpoint threshold=1.0*1' + type: string + example: 'API requests too frequent: endpoint threshold=1.0*1' tags: - Instances operationId: showInstances diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 5c90783a..5ce90b01 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -269,15 +269,12 @@ paths: type: integer example: 1234567 '429': - description: Too Many Requests + description: Too Many Requests. Legacy limiter. Plain-text body, no Retry-After header. `penalty` is not applied on this route. content: - application/json: + text/plain: schema: - type: object - properties: - detail: - type: string - example: "API requests too frequent: endpoint threshold=4.5*1" + type: string + example: "API requests too frequent: endpoint threshold=4.5*1" components: securitySchemes: ApiKeyAuth: diff --git a/api-reference/openapi/yaml/schedule_maint.yaml b/api-reference/openapi/yaml/schedule_maint.yaml index 4997c43c..b514b729 100644 --- a/api-reference/openapi/yaml/schedule_maint.yaml +++ b/api-reference/openapi/yaml/schedule_maint.yaml @@ -97,15 +97,26 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests + description: Too Many Requests. JSON body and a Retry-After header. + headers: + Retry-After: + schema: + type: integer + description: Seconds to wait. content: application/json: schema: type: object properties: - detail: + error: + type: string + example: HTTPTooManyRequests + msg: type: string - example: "API requests too frequent: endpoint threshold=2.5*1" + example: API requests too frequent + retry_after: + type: integer + example: 3 tags: - Machines components: diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index 077c2881..5f3e3b84 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -442,12 +442,13 @@ paths: '429': description: | Too many requests, or the daily search row quota is exhausted. - `error: search_quota_exceeded` includes a `Retry-After` header (seconds until the quota resets, which can be hours). + Both `HTTPTooManyRequests` and `search_quota_exceeded` include a `Retry-After` header. + The quota error's wait can be hours. headers: Retry-After: schema: type: integer - description: Seconds to wait. Present on `search_quota_exceeded`. + description: Seconds to wait. Present on both search 429s. content: application/json: schema: diff --git a/api-reference/openapi/yaml/show_charges.yaml b/api-reference/openapi/yaml/show_charges.yaml index 470f8c0e..3e4f7136 100644 --- a/api-reference/openapi/yaml/show_charges.yaml +++ b/api-reference/openapi/yaml/show_charges.yaml @@ -224,7 +224,12 @@ paths: error: auth_error msg: Invalid user key '429': - description: Too Many Requests + description: Too Many Requests. JSON body and a Retry-After header. + headers: + Retry-After: + schema: + type: integer + description: Seconds to wait. content: application/json: schema: diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 149d5da9..9eb5365b 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -144,15 +144,26 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests + description: Too Many Requests. JSON body and a Retry-After header. + headers: + Retry-After: + schema: + type: integer + description: Seconds to wait. content: application/json: schema: type: object properties: - detail: + error: + type: string + example: HTTPTooManyRequests + msg: type: string - example: "API requests too frequent: endpoint threshold=2.0*1" + example: API requests too frequent + retry_after: + type: integer + example: 2 tags: - Billing components: diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index 49bf35c9..2f5e84f8 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -504,15 +504,12 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests + description: Too Many Requests. Legacy limiter. Plain-text body, no Retry-After header. content: - application/json: + text/plain: schema: - type: object - properties: - detail: - type: string - example: "API requests too frequent: endpoint threshold=1.0*1" + type: string + example: "API requests too frequent: endpoint threshold=1.0*1" tags: - Instances components: diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 427da4d2..72e27b57 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -243,9 +243,9 @@ Below is the complete mapping of which endpoints each permission category contro ### instance\_read -SLA checks use `GET /api/v1/instances/` or `vastai show instances-v1 --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#renter-sla-scoped-key-recipe). +SLA checks use `GET /api/v1/instances/` or `vastai show instances --raw` for `target_reliability` and `instance.slaPremiumPerHour`. See the [renter SLA recipe](#renter-sla-scoped-key-recipe). -- [Show Instance](/api-reference/instances/show-instance) — v0 path; not for SLA verification (use Show Instances v1 / `show instances-v1` as in the renter recipe). +- [Show Instance](/api-reference/instances/show-instance) — v0 path; not for SLA verification (use Show Instances v1 / `vastai show instances --raw`). - [Show Instances](/api-reference/instances/show-instances) — `GET /api/v1/instances/`. For SLA fields (`target_reliability`, `search.slaPremiumPerHour`), use that API. `vastai show instances --raw` calls the same endpoint. - [Show Logs](/api-reference/instances/show-logs) - [Show SSH Keys](/api-reference/instances/show-ssh-keys) diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index bbf83e1f..9b9388bd 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -34,7 +34,7 @@ The combined API reference does not always show each operation's `x-rate-limit` | Endpoint | Safe pacing | | --- | --- | | Search offers (`POST /bundles/`) | about 10 requests per minute | -| Rent (`PUT /asks/{id}/`) | one call every 4.5 seconds; space calls at least 5 seconds apart | +| Rent (`PUT /asks/{id}/`) | At least 5 seconds between calls (server threshold 4.5 s) | | Show instances (v1) | one call per second | | Show charges | one call per second | | Show earnings and the SLA backtester | one call every 2 seconds | @@ -45,10 +45,10 @@ The combined API reference does not always show each operation's `x-rate-limit` When you hit a rate limit, you will receive **HTTP 429**. There are two families: -- **Legacy endpoints** (rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`): a plain-text body such as `API requests too frequent: endpoint threshold=…`, with no `Retry-After` header. -- **Token-bucket endpoints** (search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`): JSON `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}` with a short `Retry-After` header. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- **Legacy limiter** (plain text, no `Retry-After`): rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, and listing `PUT /api/v0/machines/create_asks/`. The body looks like `API requests too frequent: endpoint threshold=…`. The rent route does not apply a penalty on top of that threshold. +- **Token-bucket limiter** (JSON plus a `Retry-After` header): search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`, earnings, schedule maintenance, and the SLA backtester. The body is `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}`. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. -Honor `Retry-After` whenever it is present. If it is absent, back off yourself. +Honor `Retry-After` whenever it is present. If it is absent, wait at least that endpoint's pacing interval before the next call. ### How to reduce rate limit errors diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index f6e302df..008278f2 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -33,8 +33,8 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Legacy rent and show-instances calls return plain text and no `Retry-After`. -- Search and charges return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Legacy rent, show-instances, and `create_asks` calls return plain text and no `Retry-After`. +- Search, charges, earnings, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"` and a `Retry-After` header. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. The CLI never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index e844e968..2d2f6226 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -165,7 +165,7 @@ vastai create instance 1000004 --image pytorch/pytorch --disk 40 --onstart-cmd ' vastai create instance 1000001 --template_hash TEMPLATE_HASH --disk 64 --bid_price 0.1 ``` -Return value — JSON with `new_contract`, the rental contract ID for the new instance. Use this value in the console **Instances** list and with `GET /api/v1/instances/` as the instance `id` (`vastai show instances-v1 --raw` for v1 fields). It is not the search offer/ask `id` you passed to create-instance. +Return value — JSON with `new_contract`, the rental contract ID for the new instance. Use this value in the console **Instances** list and with `GET /api/v1/instances/` as the instance `id` (`vastai show instances --raw` for v1 fields). It is not the search offer/ask `id` you passed to create-instance. ```json {"success": true, "new_contract": 2000001} diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 92f5c9b8..2c4858b9 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -275,7 +275,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ `template_hash_id` is the content hash of a saved template. Include `template_hash_id` to rent from the template. Add `image` only when you want to override the template image. A request needs at least one of those fields. A template rent can send `template_hash_id` alone. Request fields override template defaults. `disk` below 8 GB is raised to 8 GB with no error, so a CLI quote at the 5 GiB default will not match the billed storage. Rent returns `invalid_price` when the offer's GPU price exceeds the platform maximum, not because `target_reliability` changed. Re-search and use a fresh offer ID. See [Create Instance](/api-reference/instances/create-instance). -**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances-v1 --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Renter SLA scoped-key recipe](/api-reference/permissions#renter-sla-scoped-key-recipe). +**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Renter SLA scoped-key recipe](/api-reference/permissions#renter-sla-scoped-key-recipe). **3. Verify.** Save `new_contract` from the rent response. Look that contract up with URL-encoded `select_filters` (`id` is a filterable column): @@ -286,10 +286,10 @@ curl -G "https://console.vast.ai/api/v1/instances/" \ --data-urlencode "limit=25" ``` -Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row (`target_reliability > 0` means the rental has an SLA). `instance.slaPremiumPerHour` is `0` until the instance is **running**, so do not treat `0` before startup as a failed SLA rent. Once it is running, that field is the SLA fee. Requires `instance_read`. You can also read the same fields with `vastai show instances-v1 --raw`. If the filter returns no row, confirm you used `new_contract` (not the offer id), then retry after a short delay, no more than about once per second (`show_instances` `x-rate-limit` threshold `1.0`). Use `after_token` paging only when listing without an `id` filter. Do not use `select_filters` alone to detect an SLA (`has_sla` is not a filterable column). +Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `target_reliability` on that row (`target_reliability > 0` means the rental has an SLA). `instance.slaPremiumPerHour` is `0` until the instance is **running**, so do not treat `0` before startup as a failed SLA rent. Once it is running, that field is the SLA fee. Requires `instance_read`. You can also read the same fields with `vastai show instances --raw`. If the filter returns no row, confirm you used `new_contract` (not the offer id), then retry after a short delay, no more than about once per second (`show_instances` `x-rate-limit` threshold `1.0`). Use `after_token` paging only when listing without an `id` filter. `has_sla` is not a filterable column. To list only SLA rentals, filter with `select_filters={"sla_r_target":{"gt":0}}`, or filter client-side on `target_reliability > 0`. - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). If you omit `limit`, the server returns at most **25** rows. A non-positive `limit` is treated as 5, then capped at 25. -- **CLI:** `vastai show instances --raw` fetches every page by default (`show instances-v1` is a hidden alias for the same command). Passing `--limit` (1–25) or `--next-token` switches to a single page. +- **CLI:** `vastai show instances --raw` fetches every page by default. `show instances-v1` is another name for the same command. Passing `--limit` (1–25) or `--next-token` switches to a single page. **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. @@ -358,7 +358,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. -**Stop vs destroy.** Vast has not published whether **Stop** ends GPU or SLA charges on an SLA rental. Budget as if a stopped SLA instance is still billed for GPU, storage, and the SLA fee. Only **Destroy** is documented to end those charges, and it deletes the disk. If your balance reaches $0 and you have no saved card, a stopped SLA instance can keep the balance negative while its data is scheduled for deletion. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. +**Stop vs destroy.** Stopping an SLA rental is not guaranteed to end GPU or SLA charges. Budget as if billing continues until you **Destroy** the instance. Destroy deletes the disk. If your balance reaches $0 and you have no saved card, a stopped SLA instance can keep the balance negative while its data is scheduled for deletion. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index 72866781..f3dc0286 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -78,7 +78,7 @@ There are separate prices and charges for: - Storage costs (in \$/GB/hr) - Bandwidth costs (in \$/TB) -You are charged the base active rental cost for every second your instance is in the active/connected state. You are charged the storage cost (which depends on the size of your storage allocation) for every single second your instance exists and is online (for all states other than offline). Stopping an instance does not avoid storage costs. +You are charged the base active rental cost for every second your instance is in the active/connected state. SLA rentals are an exception: they keep billing while the instance is offline. See [What you pay during an outage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). You are charged the storage cost (which depends on the size of your storage allocation) for every single second your instance exists and is online (for all states other than offline). Stopping an instance does not avoid storage costs. You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index bab87d2e..9d442478 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -133,7 +133,7 @@ SLA reliability is measured at the **rental contract (instance) level** using pl - **Instance fails to start** because the machine is down (driver, disk, network, or daemon) → counts against SLA reliability for that contract. Whether downtime the renter causes (their own Stop or reboot, a bad image, a container crash, or a stop at zero balance) counts against you, or earns them a credit, is not specified. Contact support before you treat that downtime as yours. - **Machine-level outage** while contracts are active → affects settlement for those contracts. -- **Brief host reboots** during active rentals may count as downtime. Vast does not publish a fixed second-level threshold in host docs — treat unplanned reboots as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance). Notice is not a cutoff that removes the credit. +- **Brief host reboots** during active rentals may count as downtime. No fixed reboot-duration threshold applies. Treat any unplanned reboot as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance). Notice is not a cutoff that removes the credit. - **Scheduled maintenance** may be partly forgiven (counted as uptime) — see [Scheduled maintenance](#scheduled-maintenance). That is not a service credit. On sliced machines, SLA settles **per rental contract**. If one GPU slice fails but others remain healthy, only contracts on the affected slice are measured for downtime. @@ -308,7 +308,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{"machine": 12345, "price_disk": CURRENT_STORAGE_PRICE, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace every `CURRENT_*` value from `vastai show machines --raw`: `listed_storage_cost`, `listed_min_gpu_count`, and whether the listing is hidden. An unedited paste is not valid JSON. `min_chunk` defaults to 1 only when offers are created or re-created. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Re-send bandwidth prices, `credit_discount_max`, `price_min_bid`, and `sla_sigma_x` right away, or the new ask keeps the defaults (bandwidth `0`, discount `0.4`, confidence `0.5`). Send `end_date` only in the full listing update below, when you mean to extend. +Replace `CURRENT_STORAGE_PRICE` and `CURRENT_MIN_CHUNK` from `vastai show machines --raw` (`listed_storage_cost` and `listed_min_gpu_count`). `show machines` does not report hidden status. Set `CURRENT_HIDDEN` from your own notes or **Set Pricing**. Sending `false` for a hidden listing makes it public. An unedited paste is not valid JSON. `min_chunk` defaults to 1 only when offers are created or re-created. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Re-send bandwidth prices, `credit_discount_max`, `price_min_bid`, and `sla_sigma_x` right away, or the new ask keeps the defaults (bandwidth `0`, discount `0.4`, confidence `0.5`). Send `end_date` only in the full listing update below, when you mean to extend. Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes Claim or Confidence in a way that would raise that contract's SLA fee. A Claim or Confidence change does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 251d1bc4..c7738915 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -35,8 +35,8 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Legacy rent and show-instances calls return plain text and no `Retry-After`. -- Search and charges return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Legacy rent, show-instances, and `create_asks` calls return plain text and no `Retry-After`. +- Search, charges, earnings, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"` and a `Retry-After` header. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. The SDK never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 854bb759..7df49eb8 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -165,7 +165,7 @@ VastAI.create_instance( ## Returns -`dict`. On success, the response includes `new_contract` — the rental contract / instance ID to use with destroy and `GET /api/v1/instances/` (`vastai show instances-v1`). The `id` you pass to `create_instance()` is the offer/ask ID from search, not `new_contract`. `create_instance()` cannot set `target_reliability`; use REST for an SLA. +`dict`. On success, the response includes `new_contract` — the rental contract / instance ID to use with destroy and `GET /api/v1/instances/` (`vastai show instances --raw`). The `id` you pass to `create_instance()` is the offer/ask ID from search, not `new_contract`. `create_instance()` cannot set `target_reliability`; use REST for an SLA. ## Example From c55136a34963cba9130c3f1419f6272b2aa670c8 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 02:21:42 -0700 Subject: [PATCH 207/250] docs(sla): address doc-review consensus (cycle 152) Use the same Stop-billing wording everywhere, and stop treating a multi-day sla_earn total as a daily series. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 2 +- guides/reference/billing.mdx | 2 +- host/hosting-overview.mdx | 4 ++-- host/sla-backtester.mdx | 12 +++++++++--- host/sla-offers.mdx | 8 ++++---- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 2c4858b9..60b50ad9 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -358,7 +358,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. -**Stop vs destroy.** Stopping an SLA rental is not guaranteed to end GPU or SLA charges. Budget as if billing continues until you **Destroy** the instance. Destroy deletes the disk. If your balance reaches $0 and you have no saved card, a stopped SLA instance can keep the balance negative while its data is scheduled for deletion. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. +**Stop vs destroy.** Stopping an SLA rental is not guaranteed to end GPU or SLA charges. Budget as if billing continues until you **Destroy** the instance. Destroy deletes the disk. To see what a stopped SLA rental cost, check that instance's row in **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy** the instance. If your balance reaches $0 and you have no saved card, a stopped SLA instance can keep the balance negative while its data is scheduled for deletion. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index f3dc0286..75d23785 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -16,7 +16,7 @@ We accept credit card payments through Stripe and crypto payments through BitPay ### Negative Balances -Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. On an SLA rental, **Stop** is not documented to end GPU or SLA charges. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. On an SLA rental, **Stop** is not guaranteed to end GPU or SLA charges. Budget as if billing continues until you **Destroy** the instance. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). **When your balance reaches zero (or below):** - Your instances are **stopped automatically**. If you rent with an SLA, a stop at zero balance is not guaranteed to end the GPU charge or the SLA fee. Top up, or **Destroy** the instance if you need those charges to stop. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 0a4a531c..95017c42 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. Existing contracts keep their original end dates in some cases, for example when the relist raises a price, or changes Claim or Confidence in a way that would raise that contract's SLA fee. A contract skipped for an SLA-fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (Claim, your reliability commitment, or Confidence, the fee margin) that would raise a contract's SLA fee is not applied to that contract. A contract skipped only for that fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. @@ -251,7 +251,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. You cannot see which active rentals carry an SLA. If SLA was on at any point during a rental that is still active, use the SLA path below. +- **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. You cannot see which active rentals carry an SLA. If SLA is enabled now, or was enabled at any point during a rental that is still active, use the SLA path. Do not use the no-SLA unlist path unless SLA was never on during a rental that is still active. - **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It stops new rentals, and it also removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter Claim and Confidence before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Use these paths in order: diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index d1767f2e..8ed7ad7f 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -280,7 +280,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** ## Fleet workflow -Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. For machines that already have SLA enabled, the replay under-counts those days. Treat `largest_day_credit` as a lower bound. `net_sla` can be off in either direction, because both fees and credits are understated. For a cleaner estimate, use a window from before SLA was enabled. See [Simulation limits](#simulation-limits). +Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. For machines that already have SLA enabled, the replay under-counts those days. Treat `largest_day_credit` as a lower bound. `net_sla` can be off in either direction, because both fees and credits are understated. For a cleaner estimate, set `START` and `END` (Unix seconds) to a window from before SLA was enabled, and set `T` to the renter target you want to model (for example `0.95`, and not above the commitment you send). See [Simulation limits](#simulation-limits). **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). @@ -296,6 +296,11 @@ Optional, for API automation only. To check one machine, use the single-machine # Optional fallbacks for machines without SLA yet (machines with SLA keep their own terms): R=0.99 P=0.6667 BT_DIR=$(mktemp -d) trap 'rm -rf "$BT_DIR"' EXIT +# Optional: START and END are Unix seconds for a pre-SLA window. T is a renter target at or below the commitment. +extra="" +[ -n "${START:-}" ] && extra="${extra}&start_date=${START}" +[ -n "${END:-}" ] && extra="${extra}&end_date=${END}" +[ -n "${T:-}" ] && extra="${extra}&r_target=${T}" machines=$(vastai show machines --raw --api-key "$VAST_API_KEY") for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ @@ -325,12 +330,13 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do out="$BT_DIR/sla_bt_$id.json" http=$(curl -s -o "$out" -w "%{http_code}" \ -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r_claim=$r&p=$p") + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=$id&r_claim=$r&p=$p${extra}") if [ "$http" != "200" ] || ! jq -e '.success == true' "$out" >/dev/null 2>&1; then echo "machine_id=$id failed http=$http body=$(jq -c '{success,error,msg}' "$out" 2>/dev/null)" >&2 sleep 3; continue fi - jq -c --arg id "$id" '{machine_id: $id, params, has_data, r_eff, r_be, + jq -c --arg id "$id" --arg start "${START:-}" --arg end "${END:-}" --arg t "${T:-}" '{machine_id: $id, params, has_data, r_eff, r_be, + start_date: $start, end_date: $end, r_target: $t, net_sla: (([.days[].client_premium_to_escrow] | add) - ([.days[].escrow_to_client_balance] | add)), largest_day_credit: ([.days[].escrow_to_client_balance] | max)}' "$out" sleep 3 diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 9d442478..a4fd2385 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -44,8 +44,8 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Claim** and **Confidence**. Enter Claim in the units the console field shows. In the API, 99% is `0.99`, not `99`. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. -8. **Verify now.** From the client account, include unverified machines (a new machine usually is) and set **Reliability target** at or below your Claim. Search hides offers whose Claim is below the target. Confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). +7. Enter **Claim** and **Confidence**. Enter Claim in the units the console field shows. Before you **Save**, confirm the SLA fee preview matches the percent you intended. In the API, 99% is `0.99`, not `99`. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. +8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your Claim. Search hides offers whose Claim is below the target. Confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -789,7 +789,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Relist with every field resent.** Relisting after an unlist creates a new ask, so stored values do not carry over. Send all of these in one `create_asks` request, using the values you recorded before unlisting: `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `sla_r_claim`, `sla_sigma_x`, `credit_discount_max`, `price_min_bid`, and `"vol_size": 0` unless you want a volume offer. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. `show machines` never returns the exact `sla_sigma_x`. Sending `end_date` or `duration` extends every active rental that ends sooner. No API field shows the latest rental end date. Check **Host → Machines** before you choose it. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Relist with every field resent.** Relisting after an unlist creates a new ask, so stored values do not carry over. Send all of these in one `create_asks` request, using the values you recorded before unlisting: `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `sla_r_claim`, `sla_sigma_x`, `credit_discount_max`, `price_min_bid`, and `"vol_size": 0` unless you want a volume offer. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. `show machines` never returns the exact `sla_sigma_x`. Sending `end_date` or `duration` extends every active rental that ends sooner. No API field shows the latest rental end date. Check **Host → Machines** for that date before you choose the `end_date` or `duration` to send. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing @@ -873,7 +873,7 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Pull several hours after UTC midnight (for example 06:00 UTC). Later corrections can change `sla_earn`, so re-pull a trailing window (`sday` six days earlier through yesterday) instead of recording a day once. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Pull several hours after UTC midnight (for example 06:00 UTC). Later corrections can change `sla_earn`. A multi-day window returns one total per machine, so it shows that the window changed, not which day. For a per-machine daily record, call earnings once per UTC day (`sday=eday=D`, no `machid`) for each of the last 7 days, at least 2 seconds apart, and compare `per_machine[].sla_earn` with the value you stored for that machine and day. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. - **Fleet, exact UTC day (one call):** omit `machid` and set `sday` and `eday` to the same day index. Read `per_machine[].sla_earn`. - **Recent window (`last_days`, coarse):** one request without `machid` returns all machines in `per_machine[]`. `last_days=1` spans yesterday and today-so-far. From 7a88a3c86271a8a35c9e2e797e1d2490c9240057 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 02:36:15 -0700 Subject: [PATCH 208/250] docs(sla): address doc-review consensus (cycle 153) Match the console commitment field, CLI SLA fee, and machine-earnings 429 to the API, and stop a fleet re-list from resetting confidence. Co-authored-by: Cursor --- api-reference/openapi.yaml | 22 +++----------- api-reference/openapi/yaml/show_earnings.yaml | 22 +++----------- api-reference/rate-limits-and-errors.mdx | 4 +-- cli/rate-limits.mdx | 4 +-- cli/reference/search-offers.mdx | 8 ++--- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 1 + host/hosting-overview.mdx | 3 +- host/sla-offers.mdx | 29 ++++++++++++------- sdk/python/rate-limits.mdx | 4 +-- 10 files changed, 41 insertions(+), 58 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 4801678a..bed0e19f 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8130,26 +8130,12 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. JSON body and a Retry-After header. - headers: - Retry-After: - schema: - type: integer - description: Seconds to wait. + description: Too Many Requests. Plain-text body, no Retry-After header. content: - application/json: + text/plain: schema: - type: object - properties: - error: - type: string - example: HTTPTooManyRequests - msg: - type: string - example: API requests too frequent - retry_after: - type: integer - example: 2 + type: string + example: 'API requests too frequent: endpoint threshold=2*1' tags: - Billing operationId: showEarnings diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 9eb5365b..2f9c969a 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -144,26 +144,12 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. JSON body and a Retry-After header. - headers: - Retry-After: - schema: - type: integer - description: Seconds to wait. + description: Too Many Requests. Plain-text body, no Retry-After header. content: - application/json: + text/plain: schema: - type: object - properties: - error: - type: string - example: HTTPTooManyRequests - msg: - type: string - example: API requests too frequent - retry_after: - type: integer - example: 2 + type: string + example: "API requests too frequent: endpoint threshold=2*1" tags: - Billing components: diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index 9b9388bd..1196bb4f 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -45,8 +45,8 @@ The combined API reference does not always show each operation's `x-rate-limit` When you hit a rate limit, you will receive **HTTP 429**. There are two families: -- **Legacy limiter** (plain text, no `Retry-After`): rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, and listing `PUT /api/v0/machines/create_asks/`. The body looks like `API requests too frequent: endpoint threshold=…`. The rent route does not apply a penalty on top of that threshold. -- **Token-bucket limiter** (JSON plus a `Retry-After` header): search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`, earnings, schedule maintenance, and the SLA backtester. The body is `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}`. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- **Legacy limiter** (plain text, no `Retry-After`): rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, listing `PUT /api/v0/machines/create_asks/`, and machine earnings `GET /api/v0/users/{user_id}/machine-earnings/`. The body looks like `API requests too frequent: endpoint threshold=…`. The rent route does not apply a penalty on top of that threshold. +- **Token-bucket limiter** (JSON plus a `Retry-After` header): search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`, the other earnings routes, schedule maintenance, and the SLA backtester. The body is `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}`. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. Honor `Retry-After` whenever it is present. If it is absent, wait at least that endpoint's pacing interval before the next call. diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 008278f2..6c43479f 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -33,8 +33,8 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Legacy rent, show-instances, and `create_asks` calls return plain text and no `Retry-After`. -- Search, charges, earnings, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"` and a `Retry-After` header. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Legacy rent, show-instances, `create_asks`, and `show earnings` (machine earnings) return plain text and no `Retry-After`. +- Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"` and a `Retry-After` header. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. The CLI never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 3deeaa70..7b3af6ee 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -187,16 +187,16 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. In `--raw` output, `dph_total` (also a sort field via `--order dph_total`) and `search.slaPremiumPerHour` are the SLA price fields. `dph_total` (alias `dph`) is also accepted as a CLI query filter, but the CLI cannot send `target_reliability`, so that filter compares the price **without** the SLA fee. To filter on the SLA-inclusive price, use the console or `POST /api/v0/bundles/` with `target_reliability`. +**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability` (console, REST, or SDK `search(..., target_reliability=…)`). The CLI cannot send `target_reliability`, so in CLI `--raw` output `search.slaPremiumPerHour` is 0 or absent and `dph_total` does not include an SLA fee. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. | Field | Meaning | | --- | --- | -| `dph_total` | Total $/hr including SLA charge when you searched with `target_reliability` | -| `search.slaPremiumPerHour` | SLA fee for that quote | +| `dph_total` | Total $/hr. Includes the SLA fee only when that search set `target_reliability` (not in CLI output) | +| `search.slaPremiumPerHour` | SLA fee for that quote. `0` or absent in CLI `--raw` output | | `expected_reliability` | Host reliability commitment (also a query key; see Available Fields) | -REST search accepts the SLA query keys `has_sla`, `expected_reliability`, and `target_reliability`. The CLI can send only `has_sla` and `expected_reliability`. A CLI `target_reliability` filter is sent as an operator object and returns HTTP 400. Search quotes SLA pricing only. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). With `--raw`, the SLA fee for that quote is `search.slaPremiumPerHour`. +REST and the SDK accept `target_reliability` and return `search.slaPremiumPerHour` for that quote. The CLI can send only `has_sla` and `expected_reliability`. A CLI `target_reliability` filter is sent as an operator object and returns HTTP 400. Do not read an SLA fee from CLI `--raw` output. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": 0.95` (a plain number; `{"eq": 0.95}` is rejected with 400). In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla` and `expected_reliability`. The warning is harmless: those fields are still sent. `target_reliability` is not in that harmless set. To self-check, run `--raw | jq 'all(.[]; .expected_reliability > 0)'` (CLI `--raw` prints a bare array of offers, not an `offers` object). diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 77b0a297..457b979d 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA Fee** line in the price breakdown. An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -The console and REST search quote SLA-inclusive prices. The CLI can only find SLA offers; its `dph_total` excludes the SLA fee. None of them turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA Fee** line, you do not have an SLA. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). +The console and REST search quote SLA-inclusive prices. The CLI can only find SLA offers; its `dph_total` excludes the SLA fee. None of them turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA Fee** line, you do not have an SLA. If that line is missing on every offer after you set a **Reliability target**, SLA may be off platform-wide (search does not return an error). Contact support. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 60b50ad9..8fd30c09 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -455,6 +455,7 @@ Host ask field `sla_r_claim` on listings is host-side; on active rentals the loc - **Prepaid / reserved-only flows** may reject SLA parameters. Use on-demand rentals for an SLA. - Offers without SLA (`expected_reliability = 0` / `has_sla=false`) are excluded when you filter with `has_sla=true` or set a positive `target_reliability`. - If SLA pricing fails for an offer, that row has no positive SLA fee (`search.slaPremiumPerHour` in the API) even though you set a target. Treat it as unpriced. Drop it before you sort by price, and do not rent it. +- If **every** row is missing `expected_reliability` and `search.slaPremiumPerHour` even though you sent `target_reliability`, SLA may be turned off platform-wide. Search does not return an error in that case. A rent that includes `target_reliability` then returns `403 sla_disabled`. Contact support. Do not treat an empty SLA filter as "no hosts offer SLA" until you have ruled this out. ## FAQ diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 95017c42..59c789c4 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (Claim, your reliability commitment, or Confidence, the fee margin) that would raise a contract's SLA fee is not applied to that contract. A contract skipped only for that fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (Claim, which is your reliability commitment, or Confidence, which is the fee margin) that would raise a contract's SLA fee is not applied to that contract. A contract skipped only for that fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. @@ -282,6 +282,7 @@ If your machine seems unlisted or missing from console search: - Confirm **Listed** status on **Host → Machines** (console). - **CLI check:** `vastai search offers 'machine_id=MACHINE_ID verified=any'` — if this returns a result, your machine is listed. The GUI may lag behind CLI visibility. +- No rows can also mean every GPU is rented or the listing is hidden. Check **Listed** and the current rentals on **Host → Machines** before you relist. Relisting creates a new ask and can extend active rentals or drop SLA terms. - Individual machines can be hard to find in broad console search; looking up by `machine_id` is the reliable check. - **Ranking check:** Use narrow filters to see similar machines, e.g. `vastai search offers 'gpu_name=RTX_4090 cpu_ram>257 cpu_ram<258'`. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a4fd2385..e73ee779 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -44,8 +44,8 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Claim** and **Confidence**. Enter Claim in the units the console field shows. Before you **Save**, confirm the SLA fee preview matches the percent you intended. In the API, 99% is `0.99`, not `99`. With no history, start **Claim** below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your Claim. Confirm the SLA fee preview, then **Save**. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. -8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your Claim. Search hides offers whose Claim is below the target. Confirm an **SLA Fee** line. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). +7. Enter **Reliability Commitment** and **Confidence**. In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. In the API, send `sla_r_claim` as a fraction (`0.99`, not `99`). With no history, start the commitment below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. +8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Search hides offers whose commitment is below the target. Confirm an **SLA Fee** line. If every offer is missing that line and `expected_reliability` even though you set a target, SLA may be off platform-wide. Search does not return an error in that case. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -233,7 +233,7 @@ On a listed machine, moving the offer end date later extends every shorter activ - **Extends shorter rentals:** a request that sends `end_date` or `duration` at the same or a lower GPU, disk, and bandwidth price. - **Skips that contract:** the request raises the GPU, disk, or bandwidth price. For some renters this records a pending price increase, and later extension requests also skip that contract until the renter accepts or declines it. A request that would raise the contract's SLA fee, or that fails an SLA check (for example `sla_r_claim: 0` or a Claim below that contract's target), also skips it. The contract keeps its end date and is missing from `upd_contracts`. - **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A skip caused only by an SLA-fee change does not stop a later request. A pending price increase does. -- **You cannot see each contract's end date.** **Host → Machines** shows the latest rental end date on the machine. No API field exposes it. +- **You cannot see each contract's end date in the documented API.** **Host → Machines** shows the latest rental end date on the machine. You cannot confirm in advance which rentals a later `end_date` will extend. Changing Claim or Confidence does not change SLA terms already locked on a contract. Only new rentals pick up the new terms. Hosts do not set the SLA fee. It changes when you change Claim or Confidence (wider Confidence raises the fee at a given target). @@ -250,7 +250,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. On a machine that already has rentals, moving the offer end date later extends every shorter SLA rental and your credit exposure. To avoid that, unlist instead of extending. See [SLA on extended contracts](#sla-on-extended-contracts). 3. Expand **SLA**. -4. Set your **reliability commitment** (the console control is **Claim**; the API field is `sla_r_claim`). Renters see it as expected reliability on the offer. Set **Confidence** too. For a new or volatile machine, start with **Wide**. Wider confidence charges a higher SLA fee, which is a cushion against credits; it does not reduce what you owe when a day misses the target. Move to **Normal** (`sla_sigma_x ≈ 0.5`) once uptime is stable. See [Confidence values](#confidence-values). +4. Set your **reliability commitment** (console label **Reliability Commitment**, entered as a percent; the API field is `sla_r_claim`, a fraction such as `0.99`). Renters see it as expected reliability on the offer. Set **Confidence** too. For a new or volatile machine, start with **Wide**. Wider confidence charges a higher SLA fee, which is a cushion against credits; it does not reduce what you owe when a day misses the target. Move to **Normal** (`sla_sigma_x ≈ 0.5`) once uptime is stable. See [Confidence values](#confidence-values). 5. Confirm the SLA fee preview, then click **Save**. On an already-listed machine, **Save** publishes SLA immediately. 6. **First publish only:** after saving pricing, click **LIST**. On a machine that is already listed, **Save** in step 5 already published SLA. Skip this step. @@ -400,12 +400,12 @@ Use this loop only to restore SLA offers that no longer appear in search on mach -Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. You cannot see per-contract end dates beforehand. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). +Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. No documented API shows each rental's end date, so you cannot confirm in advance which rentals a later `end_date` will extend. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute for the account, not for each API key. See [How rate limits are applied](/api-reference/rate-limits-and-errors#how-rate-limits-are-applied). The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. -`show machines` returns confidence only as a label, so the loop does **not** send `sla_sigma_x`. On an existing SLA ask, omitting it keeps the current confidence. If the PUT creates a **new** ask, the server sets `sla_sigma_x` to `0.5` unless you send it. Keep your own record of each machine's σ and check **Set Pricing → SLA** after any run that logs a new ask. +`show machines` returns confidence only as a label. Set `SIGMA_MAP` (`id=σ`, space-separated) from your own record before `DRY_RUN=0`. A live run skips any machine that is not in the map, because a new ask would otherwise reset `sla_sigma_x` to `0.5`. Resending the same σ on an existing ask is harmless. The post-run `WARN` is only a backstop. `PUT /api/v0/machines/create_asks/` **publishes a live listing** (same as **LIST**). The loop skips machines whose `listed` field is not `true`, so it does not republish machines you unlisted. Still keep an `ALLOWLIST` of the machine IDs you intend to automate, and confirm them on **Host → Machines** before you run with `DRY_RUN=0`. @@ -454,6 +454,10 @@ HIDDEN_IDS="${HIDDEN_IDS:-}" # Volume offers: 0 = do not create a volume offer (default). It does not delete one you already have. # Set VOL_SIZE="" only if every allowlisted machine should get the server default (half of free disk). VOL_SIZE="${VOL_SIZE:-0}" +# Your own record of each machine's confidence (σ). Required before DRY_RUN=0. +# Example: SIGMA_MAP="12345=1.0 12346=0.2" +SIGMA_MAP="${SIGMA_MAP:-}" +sigma_for() { for kv in $SIGMA_MAP; do [ "${kv%%=*}" = "$1" ] && echo "${kv#*=}" && return; done; } DRY_RUN="${DRY_RUN:-1}" if [ "$DRY_RUN" = "0" ] && [ -z "$ALLOWLIST" ]; then echo "abort: set ALLOWLIST to Listed machine IDs before DRY_RUN=0" >&2; exit 1 @@ -515,15 +519,20 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "skip $id: SLA offer still in search" >&2 continue fi - # sla_sigma_x is omitted on purpose: create_asks keeps each machine's current confidence. + SIGMA="$(sigma_for "$id")" + if [ -z "$SIGMA" ] && [ "$DRY_RUN" = "0" ]; then + echo "SKIP $id: no SIGMA_MAP entry (a new ask would reset sla_sigma_x to 0.5)" >&2 + continue + fi # price_disk is required: null or omitted resets storage price to 0.10. # Rolling (-l) listings are included. Resend duration as an integer (whole seconds) so auto-renew stays on. # A float duration returns 400. Send duration OR end_date, never both. # hidden_listing must be explicit. vol_size 0 avoids creating a volume offer. - body=$(echo "$machine" | jq -c --argjson hidden "$hidden" --arg vol "$VOL_SIZE" \ + body=$(echo "$machine" | jq -c --argjson hidden "$hidden" --arg vol "$VOL_SIZE" --arg sigma "$SIGMA" \ '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim, hidden_listing: $hidden} + + (if $sigma == "" then {} else {sla_sigma_x: ($sigma|tonumber)} end) + (if .listed_inet_up_cost == null then {} else {price_inetu: .listed_inet_up_cost} end) + (if .listed_inet_down_cost == null then {} else {price_inetd: .listed_inet_down_cost} end) + (if .credit_discount_max == null then {} else {credit_discount_max: .credit_discount_max} end) @@ -789,7 +798,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Relist with every field resent.** Relisting after an unlist creates a new ask, so stored values do not carry over. Send all of these in one `create_asks` request, using the values you recorded before unlisting: `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `sla_r_claim`, `sla_sigma_x`, `credit_discount_max`, `price_min_bid`, and `"vol_size": 0` unless you want a volume offer. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. `show machines` never returns the exact `sla_sigma_x`. Sending `end_date` or `duration` extends every active rental that ends sooner. No API field shows the latest rental end date. Check **Host → Machines** for that date before you choose the `end_date` or `duration` to send. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Relist with every field resent.** Relisting after an unlist creates a new ask, so stored values do not carry over. Send all of these in one `create_asks` request, using the values you recorded before unlisting: `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `sla_r_claim`, `sla_sigma_x`, `credit_discount_max`, `price_min_bid`, and `"vol_size": 0` unless you want a volume offer. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. `show machines` never returns the exact `sla_sigma_x`. Sending `end_date` or `duration` extends every active rental that ends sooner. No documented API shows each rental's end date. Check **Host → Machines** for the latest rental end date before you choose the `end_date` or `duration` to send. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing @@ -859,7 +868,7 @@ Weekly aggregates are window totals, not daily series — use a one-day range ab `GET /api/v0/users/me/machine-earnings/` returns SLA fields alongside compute earnings. The path user id is ignored; the account is the API key owner, so a **`billing_read`** key is enough (you do not need `user_read`). See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, back off and retry per [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, pull one exact UTC day with `sday` and `eday` after UTC rollover. Do not use `last_days=1` for that job: it returns yesterday plus today so far. When a settled day stops changing is not documented; a later correction can change `sla_earn`. +This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429 the body is plain text and there is no `Retry-After` header. Wait at least two seconds and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, pull one exact UTC day with `sday` and `eday` after UTC rollover. Do not use `last_days=1` for that job: it returns yesterday plus today so far. When a settled day stops changing is not documented; a later correction can change `sla_earn`. ```bash day=$(( $(date -u +%s) / 86400 - 1 )) diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index c7738915..250771c7 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -35,8 +35,8 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Legacy rent, show-instances, and `create_asks` calls return plain text and no `Retry-After`. -- Search, charges, earnings, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"` and a `Retry-After` header. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Legacy rent, show-instances, `create_asks`, and machine earnings return plain text and no `Retry-After`. +- Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"` and a `Retry-After` header. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. The SDK never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. From 08cc20e7973620590f40ebe0a4f500ac70c43e66 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 02:44:19 -0700 Subject: [PATCH 209/250] docs(sla): address doc-review consensus (cycle 154) Use the console names Reliability Commitment and High/Medium/Low, and send bandwidth on listing updates so a new ask is not free. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 4 +- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 12 ++-- host/sla-offers.mdx | 70 ++++++++++++---------- snippets/host/cli/list-machine.mdx | 1 + snippets/host/cli/schedule-maint.mdx | 2 +- 6 files changed, 50 insertions(+), 41 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 8fd30c09..b59f97ea 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -178,7 +178,7 @@ When you search with an SLA target, the quote is the on-demand price. Reserved-i | A | $3.50 | 99% | 95% | ~$0.04 | | B | $3.50 | 95% | 95% | much higher | -Always compare **`dph_total`**, not just GPU price, when SLA matters. Sort by `dph_total` to compare total quoted cost. +Always compare the total hourly price: the offer **Price** in the console, whose hover breakdown includes an **SLA Fee** line (API: `dph_total`). In the console, sort by price after you set **Reliability target**. ### API automation @@ -320,7 +320,7 @@ curl -s -G "https://console.vast.ai/api/v0/charges/" \ | Offer no longer exists | HTTP 400 `invalid_args` (`msg` may contain `error 404/3603`), HTTP 404 `no_such_ask` (`msg` may contain `error 404/3659` if the offer was taken mid-request), or HTTP 410 | Re-search and use a fresh offer ID. Do not retry the same ID. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | -| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. | +| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. After any retry, keep checking for the original label on your next few polls. If it appears later, destroy whichever instance you do not want. | | Too many requests | HTTP 429. Search returns JSON. `error` is `HTTPTooManyRequests` for a short limit, or `search_quota_exceeded` when the daily row quota is used up. | If `error` is `search_quota_exceeded`, stop until `Retry-After` (it can be hours). Otherwise honor the short `Retry-After`. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. Rent 429s are plain text and have no `Retry-After`. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | | CLI or SDK retried a rent on its own | The CLI and SDK retry connection errors, timeouts, and HTTP 429, 502, 503, and 504. They do not read `Retry-After`. They cannot set `target_reliability`. | For an SLA rent you send yourself, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | | Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 59c789c4..89882a7e 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (Claim, which is your reliability commitment, or Confidence, which is the fee margin) that would raise a contract's SLA fee is not applied to that contract. A contract skipped only for that fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (**Reliability Commitment**, or **Confidence**, which is the fee margin) that would raise a contract's SLA fee is not applied to that contract. A contract skipped only for that fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 8ed7ad7f..fe68c721 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -245,11 +245,11 @@ A single outage day can cost far more than many days of fees. Check that you can The two values are exactly related: `p = 1 / (1 + sla_sigma_x)`, and `sla_sigma_x = 1/p − 1`. To backtest a custom `sla_sigma_x`, pass `p = 1/(1 + sla_sigma_x)` (for example `sla_sigma_x` 0.3 → `p` 0.7692). `sla_sigma_x` is capped at 3.0, so any `p` at or below 0.25 behaves like `p=0.25`. -| Confidence `p` | Console label | Listing equivalent | -| --- | --- | --- | -| `0.83` | Tight | `sla_sigma_x ≈ 0.2` | -| `0.6667` | Normal (default) | `sla_sigma_x ≈ 0.5` | -| `0.50` | Wide | `sla_sigma_x ≈ 1.0` | +| Confidence `p` | Console | Band | Listing equivalent | +| --- | --- | --- | --- | +| `0.83` | High | Tight | `sla_sigma_x ≈ 0.2` | +| `0.6667` | Medium (default) | Normal | `sla_sigma_x ≈ 0.5` | +| `0.50` | Low | Wide | `sla_sigma_x ≈ 1.0` | Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** reduce the credit owed on a miss. @@ -268,7 +268,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** | 403 | `sla_disabled` | SLA is not currently enabled on the platform. Try again later or contact support. | | 404 | `machine_not_found` | Invalid `machine_id` | | 404 | `auth_error` | Malformed API key (wrong length) | -| 429 | — | Too many requests. Wait at least two seconds and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | +| 429 | `HTTPTooManyRequests` | JSON body and a `Retry-After` header. Wait at least that long (otherwise at least two seconds) and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). | ## Recommended workflow diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e73ee779..6a435cd8 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -39,12 +39,12 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [Auto-renew and SLA](#sla-on-extended-contracts) before you enable SLA. -2. Publish once **without** SLA. In **Set Pricing**, leave **Claim** (your reliability commitment, the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA or Claim section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. +2. Publish once **without** SLA. In **Set Pricing**, leave **Reliability Commitment** (the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Reliability Commitment** and **Confidence**. In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. In the API, send `sla_r_claim` as a fraction (`0.99`, not `99`). With no history, start the commitment below the uptime you expect to deliver, and start **Confidence** at **Wide**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. +7. Enter **Reliability Commitment** and **Confidence**. In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. In the API, send `sla_r_claim` as a fraction (`0.99`, not `99`). With no history, start the commitment below the uptime you expect to deliver, and start **Confidence** at **Low** (wide margin). Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. 8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Search hides offers whose commitment is below the target. Confirm an **SLA Fee** line. If every offer is missing that line and `expected_reliability` even though you set a target, SLA may be off platform-wide. Search does not return an error in that case. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). @@ -84,7 +84,7 @@ On an outage day the renter is still charged the normal hourly rate, and you may SLA is an optional reliability promise on **on-demand** rentals. You do not have to offer it. -1. **You (the host)** state a **reliability commitment**: how often you expect the machine to be up. The API field is `sla_r_claim`. The console may still label this **Claim**. +1. **You (the host)** state a **reliability commitment**: how often you expect the machine to be up. In the console the field is **Reliability Commitment** (a percent). The API field is `sla_r_claim` (a fraction, so 99% is `0.99`). 2. You also set **Confidence**: how much pricing margin is built into the SLA fee around your commitment. **Tight** means a smaller fee. **Wide** means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. @@ -106,7 +106,7 @@ The field names for the reliability commitment (`sla_r_claim`), confidence, and In **Host → Machines → Set Pricing → SLA** you set host knobs only: -- **Reliability commitment** — how often you expect the machine to be up (shown to clients as `expected_reliability`; API field `sla_r_claim`; the console may still label this Claim). +- **Reliability commitment** — how often you expect the machine to be up (console: **Reliability Commitment**; shown to clients as `expected_reliability`; API field `sla_r_claim`). - **Confidence** — how much pricing margin is built into the SLA fee around your commitment. **Tight** means a smaller fee. **Wide** means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). Clients choose their own **reliability target** at search and rent time. You do **not** set the client target on the listing. @@ -166,8 +166,8 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Concept | Console | Listing API | Backtester | Client sees / sets | | --- | --- | --- | --- | --- | -| Reliability commitment | Claim | `sla_r_claim` | `r_claim` | `expected_reliability` | -| Confidence | Confidence / spread | `sla_sigma_x` | `p` (different scale) | — | +| Reliability commitment | **Reliability Commitment** (older text may say Claim) | `sla_r_claim` | `r_claim` | `expected_reliability` | +| Confidence | **High** / **Medium** / **Low** | `sla_sigma_x` | `p` (different scale) | — | | Reliability target | — (client-chosen) | — (not on asks) | `r_target` (optional; defaults to `r_claim`) | `target_reliability` in search | | All-in hourly price | — | — | — | `dph_total` (compute plus SLA fee when enabled) | @@ -186,17 +186,17 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r ### Confidence values -In the console, pick **Tight**, **Normal**, or **Wide**. You do not need the table unless you use the API or the backtester. In `show machines`, `high` means Tight and `low` means Wide. A `low` label is a deliberate wide margin, not a weak setting. +In the console, pick **High**, **Medium**, or **Low**. High is a tight margin (smaller SLA fee). Low is a wide margin (larger SLA fee), not a weak setting. You do not need the table unless you use the API or the backtester. -| Console label | API `sla_sigma_x` (σ) | Backtester `p` | `show machines` | Pricing effect | -| --- | --- | --- | --- | --- | -| Tight | `0.2` (band σ ≤ 0.32) | ~0.83 | `high` | Lowest client SLA fees at a given target | -| Normal (default) | `0.5` (band σ ≤ 0.71) | ~0.6667 | `medium` | Balanced | -| Wide | `1.0` (band σ above 0.71) | ~0.50 | `low` | Highest client SLA fees at a given target | +| Console | Band | API `sla_sigma_x` (σ) | Backtester `p` | `show machines` | Pricing effect | +| --- | --- | --- | --- | --- | --- | +| High | Tight | `0.2` (band σ ≤ 0.32) | ~0.83 | `high` | Lowest client SLA fees at a given target | +| Medium | Normal (default) | `0.5` (band σ ≤ 0.71) | ~0.6667 | `medium` | Balanced | +| Low | Wide | `1.0` (band σ above 0.71) | ~0.50 | `low` | Highest client SLA fees at a given target | **Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). -**Tighter confidence** (tighter spread; console label **Tight**) → lower client SLA fees (more competitive `dph_total`) and less fee income to offset a miss. **Wider confidence** (console label **Wide**) → higher client SLA fees, which is a cushion, not a smaller credit. For a new or volatile machine, start with **Wide**, then move to **Normal** once uptime is stable. Confidence does **not** change the credit formula when a target is missed — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. +**High** (tight margin) → lower client SLA fees (more competitive `dph_total`) and less fee income to offset a miss. **Low** (wide margin) → higher client SLA fees, which is a cushion, not a smaller credit. For a new or volatile machine, start with **Low**, then move to **Medium** once uptime is stable. Confidence does **not** change the credit formula when a target is missed — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. ### Validation rules @@ -231,11 +231,11 @@ For planning, assume a bad day can cost up to one full day of covered compute fo On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. - **Extends shorter rentals:** a request that sends `end_date` or `duration` at the same or a lower GPU, disk, and bandwidth price. -- **Skips that contract:** the request raises the GPU, disk, or bandwidth price. For some renters this records a pending price increase, and later extension requests also skip that contract until the renter accepts or declines it. A request that would raise the contract's SLA fee, or that fails an SLA check (for example `sla_r_claim: 0` or a Claim below that contract's target), also skips it. The contract keeps its end date and is missing from `upd_contracts`. +- **Skips that contract:** the request raises the GPU, disk, or bandwidth price. For some renters this records a pending price increase, and later extension requests also skip that contract until the renter accepts or declines it. A request that would raise the contract's SLA fee, or that fails an SLA check (for example `sla_r_claim: 0` or a reliability commitment below that contract's target), also skips it. The contract keeps its end date and is missing from `upd_contracts`. - **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A skip caused only by an SLA-fee change does not stop a later request. A pending price increase does. - **You cannot see each contract's end date in the documented API.** **Host → Machines** shows the latest rental end date on the machine. You cannot confirm in advance which rentals a later `end_date` will extend. -Changing Claim or Confidence does not change SLA terms already locked on a contract. Only new rentals pick up the new terms. Hosts do not set the SLA fee. It changes when you change Claim or Confidence (wider Confidence raises the fee at a given target). +Changing the reliability commitment or Confidence does not change SLA terms already locked on a contract. Only new rentals pick up the new terms. Hosts do not set the SLA fee. It changes when you change the reliability commitment or Confidence (a wider margin, console **Low**, raises the fee at a given target). Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -250,7 +250,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover 1. Open your machine on the [Host Machines page](https://cloud.vast.ai/host/machines) → **Set Pricing**. 2. Set base listing fields first (GPU price, offer end date, rental types) if this is a new listing. On a machine that already has rentals, moving the offer end date later extends every shorter SLA rental and your credit exposure. To avoid that, unlist instead of extending. See [SLA on extended contracts](#sla-on-extended-contracts). 3. Expand **SLA**. -4. Set your **reliability commitment** (console label **Reliability Commitment**, entered as a percent; the API field is `sla_r_claim`, a fraction such as `0.99`). Renters see it as expected reliability on the offer. Set **Confidence** too. For a new or volatile machine, start with **Wide**. Wider confidence charges a higher SLA fee, which is a cushion against credits; it does not reduce what you owe when a day misses the target. Move to **Normal** (`sla_sigma_x ≈ 0.5`) once uptime is stable. See [Confidence values](#confidence-values). +4. Set your **reliability commitment** (console label **Reliability Commitment**, entered as a percent; the API field is `sla_r_claim`, a fraction such as `0.99`). Renters see it as expected reliability on the offer. Set **Confidence** too. For a new or volatile machine, start with **Low** (wide margin, higher SLA fee). That cushion does not reduce what you owe when a day misses the target. Move to **Medium** (`sla_sigma_x ≈ 0.5`) once uptime is stable. See [Confidence values](#confidence-values). 5. Confirm the SLA fee preview, then click **Save**. On an already-listed machine, **Save** publishes SLA immediately. 6. **First publish only:** after saving pricing, click **LIST**. On a machine that is already listed, **Save** in step 5 already published SLA. Skip this step. @@ -258,9 +258,9 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover If the machine is already **listed**: -1. Open **Host → Machines → Set Pricing → SLA**, set Claim and Confidence, then click **Save**. +1. Open **Host → Machines → Set Pricing → SLA**, set **Reliability Commitment** and **Confidence**, then click **Save**. 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. -3. To stop offering SLA on **new** rentals, set **Claim** to `0` and **Save**. On an already-listed machine, **Save** updates the live offer; you do not need to click **LIST** again. Active contracts keep their SLA terms until they end. API users: send the full `create_asks` body with `"sla_r_claim": 0` (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). +3. To stop offering SLA on **new** rentals, set **Reliability Commitment** to `0` and **Save**. On an already-listed machine, **Save** updates the live offer; you do not need to click **LIST** again. Active contracts keep their SLA terms until they end. API users: send the full `create_asks` body with `"sla_r_claim": 0` (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). 4. Verify after listing: - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. - **Search:** `dph_total` includes the SLA fee at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). @@ -298,20 +298,20 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons Some omitted fields reset to defaults (for example `price_disk`, `hidden_listing`, and `duration`). Read the warning under [Full listing update](#full-listing-update-existing-ask) before you copy a body. `"vol_size": 0` keeps a new volume offer from being created. It does not delete a volume offer you already have. ```bash -# Change Claim or Confidence only. Omitting end_date and duration does not extend rentals. +# Change the reliability commitment or confidence only. Omitting end_date and duration does not extend rentals. # "vol_size": 0 keeps volume offers off. Remove it only if this machine should have a volume offer. # Rolling listings: omit duration to turn auto-renew off without extending rentals. # Sending integer duration keeps auto-renew on and extends every shorter rental. curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": CURRENT_STORAGE_PRICE, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": CURRENT_STORAGE_PRICE, "price_inetu": CURRENT_INET_UP, "price_inetd": CURRENT_INET_DOWN, "credit_discount_max": CURRENT_DISCOUNT, "price_min_bid": CURRENT_MIN_BID, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `CURRENT_STORAGE_PRICE` and `CURRENT_MIN_CHUNK` from `vastai show machines --raw` (`listed_storage_cost` and `listed_min_gpu_count`). `show machines` does not report hidden status. Set `CURRENT_HIDDEN` from your own notes or **Set Pricing**. Sending `false` for a hidden listing makes it public. An unedited paste is not valid JSON. `min_chunk` defaults to 1 only when offers are created or re-created. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Re-send bandwidth prices, `credit_discount_max`, `price_min_bid`, and `sla_sigma_x` right away, or the new ask keeps the defaults (bandwidth `0`, discount `0.4`, confidence `0.5`). Send `end_date` only in the full listing update below, when you mean to extend. +Replace `CURRENT_STORAGE_PRICE`, `CURRENT_INET_UP`, `CURRENT_INET_DOWN`, `CURRENT_DISCOUNT`, `CURRENT_MIN_BID`, and `CURRENT_MIN_CHUNK` from `vastai show machines --raw` (`listed_storage_cost`, `listed_inet_up_cost`, `listed_inet_down_cost`, `credit_discount_max`, `min_bid_price`, and `listed_min_gpu_count`). `min_bid_price` is host-side, net of the platform fee. `show machines` does not report hidden status. Set `CURRENT_HIDDEN` from your own notes or **Set Pricing**. Sending `false` for a hidden listing makes it public. An unedited paste is not valid JSON. Include bandwidth, discount, and min bid in the body so a new ask does not publish at $0 bandwidth or the 0.4 discount default. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Check those fields in the response. Send `end_date` only in the full listing update below, when you mean to extend. -Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes Claim or Confidence in a way that would raise that contract's SLA fee. A Claim or Confidence change does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). +Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes the reliability commitment or Confidence in a way that would raise that contract's SLA fee. A reliability-commitment or Confidence change does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). #### Full listing update (existing ask) @@ -326,6 +326,10 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ "machine": 12345, "price_gpu": CURRENT_GPU_PRICE, "price_disk": CURRENT_STORAGE_PRICE, + "price_inetu": CURRENT_INET_UP, + "price_inetd": CURRENT_INET_DOWN, + "credit_discount_max": CURRENT_DISCOUNT, + "price_min_bid": CURRENT_MIN_BID, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, @@ -350,6 +354,10 @@ SLA fields example (existing listing, no extension). Same fields as the curl abo "machine": 12345, "price_gpu": CURRENT_GPU_PRICE, "price_disk": CURRENT_STORAGE_PRICE, + "price_inetu": CURRENT_INET_UP, + "price_inetd": CURRENT_INET_DOWN, + "credit_discount_max": CURRENT_DISCOUNT, + "price_min_bid": CURRENT_MIN_BID, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, @@ -365,20 +373,20 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - `price_gpu` is kept if omitted. - `price_disk` resets to **$0.10/GB/month** if omitted or `null`. -- `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing, and nothing is extended). Sending integer `duration` keeps auto-renew on and extends every shorter rental, including SLA rentals. There is no way to change Claim or Confidence on a rolling listing while keeping auto-renew on and not extending rentals. +- `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing, and nothing is extended). Sending integer `duration` keeps auto-renew on and extends every shorter rental, including SLA rentals. There is no way to change the reliability commitment or Confidence on a rolling listing while keeping auto-renew on and not extending rentals. - `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. - `min_chunk` defaults to **1** when offers are created or re-created (first publish, or relisting after an unlist). On an already-listed machine, omitting it does not change the current minimum. Still send `listed_min_gpu_count` so a later relist does not slice the machine by accident. - `vol_size` omitted on a machine with no volume offer creates one sized at half the free disk. Send `"vol_size": 0` to keep that from happening. `0` does not delete a volume offer that already exists. - On a **new** ask (first publish, or a new offer after unlist), omitted `price_inetu` and `price_inetd` become `0` (free bandwidth) and omitted `credit_discount_max` becomes `0.4`. Updating an existing ask keeps those values when they are omitted. Send `listed_inet_up_cost`, `listed_inet_down_cost`, and `credit_discount_max` when you create the offer. - Send **either** `duration` (integer seconds; a float such as `2592000.0` returns 400 `Invalid duration`) **or** `end_date`, never both. Sending both returns `400` `Cannot set both duration and end_date`. -Always read the current listing and send `price_disk`. To change Claim or Confidence on a rented machine **without** extending rentals, omit both `duration` and `end_date`. The stored end date stays, and no contract is extended. Omitting `duration` on a rolling listing turns auto-renew off. Send `duration` (integer seconds) or `end_date` only when you mean to keep auto-renew or to extend. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. +Always read the current listing and send `price_disk`. To change the reliability commitment or Confidence on a rented machine **without** extending rentals, omit both `duration` and `end_date`. The stored end date stays, and no contract is extended. Omitting `duration` on a rolling listing turns auto-renew off. Send `duration` (integer seconds) or `end_date` only when you mean to keep auto-renew or to extend. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. Read current listing fields from `vastai show machines --raw`: ```bash -vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, listed, sla_reliability_claim, sla_confidence, listed_gpu_cost, listed_storage_cost, listed_min_gpu_count, end_date, duration}' +vastai show machines --raw | jq '.machines[] | select(.id == 12345 or .id == "12345") | {id, listed, sla_reliability_claim, sla_confidence, listed_gpu_cost, listed_storage_cost, listed_inet_up_cost, listed_inet_down_cost, credit_discount_max, min_bid_price, listed_min_gpu_count, end_date, duration}' ``` REST equivalent: `GET /api/v0/machines/` (the CLI sends `?owner=me`). The account is the API key owner; a `?user_id=` query is ignored. @@ -563,7 +571,7 @@ Fetch the fleet once before the loop — do not call `show machines --raw` insid -**SLA-only update (existing ask only).** Use the partial body under [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). Omit `duration` and `end_date` unless you intend to extend the offer or keep auto-renew. Do **not** use that body for a first listing. Start new or volatile machines at Wide, not Tight. +**SLA-only update (existing ask only).** Use the partial body under [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). Omit `duration` and `end_date` unless you intend to extend the offer or keep auto-renew. Do **not** use that body for a first listing. Start new or volatile machines at **Low** (wide margin), not **High**. **Disable SLA on new rentals** — set `sla_r_claim` to `0` (active contracts keep their terms). This request publishes a live listing (same as **LIST**), so don't run it on machines you have unlisted. @@ -670,7 +678,7 @@ The **reliability commitment** is your belief and pricing knob. The client's **r ### If the client's target is missed -A single bad day can wipe out weeks or months of SLA fees. In the example below, a day at the client's target boundary costs about 44 days of collected SLA fees, and a full outage day costs about 88 days. Lower renter targets carry lower fees for a similar credit, so the ratio can be higher than this example. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. +A single bad day can wipe out weeks or months of SLA fees. In the example below, a day about 1–2 points below the client's target (~93–94% blended, not a day that exactly meets the target) costs about 44 days of collected SLA fees, and a full outage day costs about 88 days. Lower renter targets carry lower fees for a similar credit, so the ratio can be higher than this example. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. These scenarios show settlement when the blended measure falls **below** a 95% client target. They are illustrations, not typical strong days: @@ -680,7 +688,7 @@ These scenarios show settlement when the blended measure falls **below** a 95% c | Blended measure ~93–94% (illustrative shortfall) | −$42 (credit you owe) | | Well below target (~90% or less) | −$84 (large credit owed) | -To put the asymmetry in perspective: at about $0.97/day in SLA fees, it takes roughly 44 strong days to accumulate the $42 you could lose on a single day at the target boundary. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use Claim 99%, Normal confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. +To put the asymmetry in perspective: at about $0.97/day in SLA fees, it takes roughly 44 strong days to accumulate the $42 you could lose on a single day about 1–2 points below the target. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use a 99% commitment, Medium confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. Your SLA loss on a normal settlement day is tied to that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). Vast does not publish whether the closing settlement on a contract's last day can exceed that. Use the backtester's largest simulated day as a planning figure, not a cap. @@ -740,7 +748,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ `sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). +**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints -ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -769,7 +777,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Console** 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). - 2. Write down every field on **Set Pricing** (price, minimum GPUs, end date, storage price, bandwidth, Claim, Confidence, reserved discount, and min bid). If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. + 2. Write down every field on **Set Pricing** (price, minimum GPUs, end date, storage price, bandwidth, **Reliability Commitment**, **Confidence**, reserved discount, and min bid). If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. @@ -784,7 +792,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 1. **Notify renters.** `echo y | vastai schedule maint MACHINE_ID --sdate "$(( $(date -u +%s) + 60 ))" --duration HOURS --maintenance_category other`. One minute ahead still counts as an unplanned window. See [Set a maintenance window](/host/set-maintenance-window). 2. **Get your current terms before you unlist.** If the machine is still visible, save them now. If it is not, use your own notes. After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, `credit_discount_max`, and SLA terms. The snapshot also omits hidden status (`hidden_listing`) and the exact `sla_sigma_x`. Write those down too. - **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, Claim, Confidence (Tight, Normal, or Wide), the reserved discount, and the interruptible min bid. An omitted reserved discount on a new ask becomes `0.4`. + **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, **Reliability Commitment**, **Confidence** (**High**, **Medium**, or **Low**), the reserved discount, and the interruptible min bid. An omitted reserved discount on a new ask becomes `0.4`. ```bash vastai show machines --raw --api-key "$VAST_API_KEY" \ diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 9c1941ef..52f7df2d 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -17,6 +17,7 @@ On an existing listing, omitted GPU price, bandwidth prices, reserved discount, **Other cautions:** - **Passing `-e` or `-l` can extend active rentals,** including SLA contracts. Normal CLI output does not print that. Pass `--raw` and read `.results[0].upd_contracts`. +- **After an unlist, the relist is a new ask.** Omitted `-u`/`-d` publish $0 bandwidth, omitted `-r` becomes `0.4`, and omitted `-m` becomes 1. Pass all of them. - **`-m` defaults to 1.** On an existing listing that has no effect. On a first listing, or a relist after unlist, it splits the machine into single-GPU offers, and each one can be its own SLA contract. Always pass `-m` with the min GPU count you intend. - **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores listed SLA offers that are missing from search, on machines with no rentals. It does not change prices. A hidden listing is also missing from search, so set `HIDDEN_IDS` or the live run makes it public. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 7143c1ea..0adc1757 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -65,7 +65,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(( $(date -u +%s) + 60 ))" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine, and it asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID` and confirm the cancel succeeded before you recreate windows. To reschedule, cancel first, then recreate each window you still want, as far ahead as you can. Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine, and it asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID` and confirm the cancel succeeded with `vastai show maints -ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)) before you recreate windows. To reschedule, cancel first, then recreate each window you still want, as far ahead as you can. Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. ## Examples From bf306505b445a6d39e3622fafe7fa4c33dd226cb Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 02:54:03 -0700 Subject: [PATCH 210/250] docs(sla): address doc-review consensus (cycle 155) Use Reliability Commitment everywhere, and fix the show-maints flag and SDK search claim that did not match the CLI. Co-authored-by: Cursor --- cli/rate-limits.mdx | 2 +- cli/reference/search-offers.mdx | 4 ++-- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 9 +++++---- guides/reference/billing.mdx | 2 +- host/hosting-overview.mdx | 10 +++++----- host/sla-offers.mdx | 16 ++++++++-------- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 2 +- snippets/host/cli/show-maints.mdx | 6 +++--- snippets/host/sdk/list-machine.mdx | 2 +- 11 files changed, 29 insertions(+), 28 deletions(-) diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 6c43479f..02df6ef5 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -47,7 +47,7 @@ The CLI retries a failed request on HTTP 429, 502, 503, and 504, and on connecti - **Backoff:** starts at 0.15 seconds, multiplied by 1.5 after each attempt. The CLI does not read `Retry-After`. - To send a request once, use `--retry 1`. Do not use `--retry 0`. It sends no request and the command fails. -Any rent can be sent twice if the first request reached the server and the connection then failed. Set a unique `--label` and check your instances for it before you rent again. The CLI and SDK cannot turn SLA on; SLA rentals use the console or REST. Use the same label check in your own retry logic. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). +Any rent can be sent twice if the first request reached the server and the connection then failed. The same applies to `vastai schedule maint` and `vastai list machine`: a retry after a timeout can create a second maintenance window or a second ask. For those commands in scripts, pass `--retry 1` and confirm the result before you run the command again. Set a unique `--label` and check your instances for it before you rent again. The CLI and SDK cannot turn SLA on; SLA rentals use the console or REST. Use the same label check in your own retry logic. See [SLA API automation](/guides/instances/choosing/sla-coverage#api-automation). The CLI retries 429, 502, 503, 504, connection errors, and timeouts. Other HTTP errors are reported immediately. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 7b3af6ee..a33fe819 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -187,7 +187,7 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability` (console, REST, or SDK `search(..., target_reliability=…)`). The CLI cannot send `target_reliability`, so in CLI `--raw` output `search.slaPremiumPerHour` is 0 or absent and `dph_total` does not include an SLA fee. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. +**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability` (console or REST). The CLI and the Python SDK `search_offers()` cannot send `target_reliability`. Adding it to a query string returns HTTP 400. In CLI `--raw` output `search.slaPremiumPerHour` is 0 or absent and `dph_total` does not include an SLA fee. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. | Field | Meaning | | --- | --- | @@ -196,7 +196,7 @@ bool = True | False | `expected_reliability` | Host reliability commitment (also a query key; see Available Fields) | -REST and the SDK accept `target_reliability` and return `search.slaPremiumPerHour` for that quote. The CLI can send only `has_sla` and `expected_reliability`. A CLI `target_reliability` filter is sent as an operator object and returns HTTP 400. Do not read an SLA fee from CLI `--raw` output. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). +REST accepts `target_reliability` and returns `search.slaPremiumPerHour` for that quote. The CLI and the Python SDK `search_offers()` cannot. A CLI `target_reliability` filter is sent as an operator object and returns HTTP 400. Do not read an SLA fee from CLI `--raw` output. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": 0.95` (a plain number; `{"eq": 0.95}` is rejected with 400). In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla` and `expected_reliability`. The warning is harmless: those fields are still sent. `target_reliability` is not in that harmless set. To self-check, run `--raw | jq 'all(.[]; .expected_reliability > 0)'` (CLI `--raw` prints a bare array of offers, not an `offers` object). diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 457b979d..659c1d1b 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -112,7 +112,7 @@ If you get this error when clicking the RENT button, the specific machine/GPU sl Startup time depends on the template and is usually under 5 minutes. If waiting over 20 minutes: - Ensure you're using a recommended template - Try a different machine -- Note: You're not charged while instances are loading +- Note: On a rental without an SLA, you're not charged while the instance is loading. Whether an SLA rental is billed during Loading is not specified. See [SLA](/guides/instances/choosing/sla-coverage). - With slow internet and large images, downloads can take an hour or more If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy**. Destroy ends the rental and permanently deletes the instance and its disk, so copy off anything you need first. If you rented with an SLA, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index b59f97ea..66e57001 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -103,7 +103,7 @@ Bandwidth is billed separately, based on usage (`inet_*` rates), and is **not** ### Example: H100 at $3.50/hr GPU -Searching with a **reliability target of 95%** on an offer where the host's **reliability commitment is 99%** with normal confidence: +Searching with a **reliability target of 95%** on an offer where the host's **reliability commitment is 99%** with **Medium** confidence: | Cost component | Approx. rate | | --- | --- | @@ -211,7 +211,7 @@ Web app: [cloud.vast.ai](https://cloud.vast.ai). REST examples use `https://cons For repeated search calls, `POST /api/v0/bundles/` is rate-limited. On HTTP 429, if `error` is `search_quota_exceeded`, wait for `Retry-After` (it can be hours). A shorter search limit returns `"error": "HTTPTooManyRequests"` and a short `Retry-After`. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). -**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. Rows from every query, including shards, count against one daily search row quota that varies by account. Size `limit` and the number of shards to fit that budget. See the **Daily search row quota** row below and [Rate Limits and Errors](/api-reference/rate-limits-and-errors). +**1. Search** (prices `dph_total` at your target — include storage explicitly so quotes are comparable). Set `limit` explicitly when you compare many offers. Bundles search has **no pagination** (no offset or page token)—one response returns at most `limit` rows for that query. OpenAPI does not document a maximum `limit`; do not assume a single call walks the full market. To scan a broader SLA market, shard queries with filters such as `gpu_name`, `geolocation`, or `machine_id`, and back off on HTTP 429. Rows from every query, including shards, count against one daily search row quota that varies by account. No response header reports how much of that quota is left. Keep `limit` small and do not re-run full sweeps. See the **Daily search row quota** row below and [Rate Limits and Errors](/api-reference/rate-limits-and-errors). ```bash curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ @@ -303,11 +303,12 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. If `next_token` is not `null`, repeat the request with `after_token` set to that value before you treat a missing `sla` item as unsettled. `limit` defaults to 100, so a busy account can put the contract on a later page. ```bash +# YOUR_API_KEY is the same key as the earlier steps. NEW_CONTRACT is the contract id from the rent response. curl -s -G "https://console.vast.ai/api/v0/charges/" \ - -H "Authorization: Bearer $VAST_API_KEY" \ + -H "Authorization: Bearer YOUR_API_KEY" \ --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1767311999}}' \ --data-urlencode "limit=500" \ - | jq --arg s "instance-$NEW_CONTRACT" '.results[] | select(.source == $s) | .items[] | select(.type == "sla") | .amount' + | jq --arg s "instance-NEW_CONTRACT" '.results[] | select(.source == $s) | .items[] | select(.type == "sla") | .amount' ``` **Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read Charges after settlement (see [Settlement timing](#settlement-timing)). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index 75d23785..a9927943 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -195,7 +195,7 @@ Before buying credit with Stripe you must add a card! ### Am I charged for "Loading" instances? -No, you are not charged when it says "Loading". +No, you are not charged when it says "Loading" on a rental without an SLA. Whether Loading time is billed on an SLA rental is not specified here. Budget the wait as if the rental can still be charging, and check **Charges** the next UTC day. ### What happens if my account balance is negative? diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 89882a7e..256fbc3a 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -195,7 +195,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. Lowering Claim or widening Confidence in that same request also skips any SLA contract whose fee would rise. A later request can still extend it. For SLA rentals, an extension also extends service-credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. Lowering your **Reliability Commitment** or moving **Confidence** toward **Low** in that same request also skips any SLA contract whose fee would rise. A later request can still extend it. For SLA rentals, an extension also extends service-credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). ## Testing your own machine @@ -223,7 +223,7 @@ Then for each machine id you will need to find the available **offer/ask IDs** ( Replace 12345 with your actual machine ID in question. You can see the number of available listings as well as information about the machine. This is the fastest way to also see all the offers listed for a given machine. The website GUI stacks similar offers and so it is not easy to see all the listings for a given machine. That is not a problem for the CLI. -Take the **offer/ask ID** from the first column of search results and use it with `create instance`. This creates a **test rental billed to your separate client account** like any other rental (it is not free). Host earnings offset client spend only after rentals settle. This example loads the latest pytorch image along with both jupyter and ssh direct launch modes. +Take the **offer/ask ID** from the first column of search results and use it with `create instance`. This creates a **test rental billed to your separate client account** like any other rental (it is not free). The client account is charged like any renter. Your host account earns from the rental as usual, but the two balances are separate. Add enough credit to the client account to cover the test, including any SLA fee. This example loads the latest pytorch image along with both jupyter and ssh direct launch modes. ```text Text vastai create instance --api-key "$CLIENT_API_KEY" --image pytorch/pytorch:latest --jupyter --direct --env '-e TZ=PDT -p 22:22 -p 8080:8080' @@ -251,10 +251,10 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **No SLA rentals:** unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. You cannot see which active rentals carry an SLA. If SLA is enabled now, or was enabled at any point during a rental that is still active, use the SLA path. Do not use the no-SLA unlist path unless SLA was never on during a rental that is still active. -- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It stops new rentals, and it also removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter Claim and Confidence before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **No SLA rentals:** Use this path only if SLA has never been on while any current rental was active. Otherwise use the SLA path below. Unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. +- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It stops new rentals, and it also removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter **Reliability Commitment** and **Confidence** before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). -Use these paths in order: +Pick the path that matches your situation: 1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. 2. **Planned downtime with active renters:** Schedule as far ahead as you can from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 6a435cd8..5d0db4ad 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -85,7 +85,7 @@ On an outage day the renter is still charged the normal hourly rate, and you may SLA is an optional reliability promise on **on-demand** rentals. You do not have to offer it. 1. **You (the host)** state a **reliability commitment**: how often you expect the machine to be up. In the console the field is **Reliability Commitment** (a percent). The API field is `sla_r_claim` (a fraction, so 99% is `0.99`). -2. You also set **Confidence**: how much pricing margin is built into the SLA fee around your commitment. **Tight** means a smaller fee. **Wide** means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). +2. You also set **Confidence**: how much pricing margin is built into the SLA fee around your commitment. **High** (tight margin) means a smaller fee. **Low** (wide margin) means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. @@ -107,7 +107,7 @@ The field names for the reliability commitment (`sla_r_claim`), confidence, and In **Host → Machines → Set Pricing → SLA** you set host knobs only: - **Reliability commitment** — how often you expect the machine to be up (console: **Reliability Commitment**; shown to clients as `expected_reliability`; API field `sla_r_claim`). -- **Confidence** — how much pricing margin is built into the SLA fee around your commitment. **Tight** means a smaller fee. **Wide** means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). +- **Confidence** — how much pricing margin is built into the SLA fee around your commitment. **High** (tight margin) means a smaller fee. **Low** (wide margin) means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). Clients choose their own **reliability target** at search and rent time. You do **not** set the client target on the listing. @@ -115,7 +115,7 @@ Clients choose their own **reliability target** at search and rent time. You do Think of an SLA offer as two host ideas plus one client choice: 1. **Your reliability commitment** — what you believe your machine will deliver (`sla_r_claim`). Setting this above `0` enables SLA on the offer. -2. **Your confidence** — how much pricing margin is built into the SLA fee around that commitment. **Tight** means a smaller fee. **Wide** means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). +2. **Your confidence** — how much pricing margin is built into the SLA fee around that commitment. **High** (tight margin) means a smaller fee. **Low** (wide margin) means a larger fee. Confidence never changes the credit you owe. See [Confidence values](#confidence-values). 3. **Client reliability target** — chosen by the renter via search (`target_reliability`). Settlement and SLA fee sizing use this target. A renter's target must be **at or below** your reliability commitment. Search hides offers whose commitment is below the target, and rent rejects that combination. When a client rents an on-demand instance on your SLA-listed offer with a chosen target: @@ -166,7 +166,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Concept | Console | Listing API | Backtester | Client sees / sets | | --- | --- | --- | --- | --- | -| Reliability commitment | **Reliability Commitment** (older text may say Claim) | `sla_r_claim` | `r_claim` | `expected_reliability` | +| Reliability commitment | **Reliability Commitment** | `sla_r_claim` | `r_claim` | `expected_reliability` | | Confidence | **High** / **Medium** / **Low** | `sla_sigma_x` | `p` (different scale) | — | | Reliability target | — (client-chosen) | — (not on asks) | `r_target` (optional; defaults to `r_claim`) | `target_reliability` in search | | All-in hourly price | — | — | — | `dph_total` (compute plus SLA fee when enabled) | @@ -235,7 +235,7 @@ On a listed machine, moving the offer end date later extends every shorter activ - **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A skip caused only by an SLA-fee change does not stop a later request. A pending price increase does. - **You cannot see each contract's end date in the documented API.** **Host → Machines** shows the latest rental end date on the machine. You cannot confirm in advance which rentals a later `end_date` will extend. -Changing the reliability commitment or Confidence does not change SLA terms already locked on a contract. Only new rentals pick up the new terms. Hosts do not set the SLA fee. It changes when you change the reliability commitment or Confidence (a wider margin, console **Low**, raises the fee at a given target). +Changing the reliability commitment or Confidence does not change the SLA fee already locked on a contract. Only new rentals pick up the new terms. Extending a contract re-checks it against your current settings. If those settings would raise that renter's SLA fee, the contract is not extended and keeps its original end date. Hosts do not set the SLA fee. It changes when you change the reliability commitment or Confidence (a wider margin, console **Low**, raises the fee at a given target). Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -619,7 +619,7 @@ A non-empty `upd_contracts` means this request extended live rentals. Each contr ## Economics walkthrough -**Setup:** You list an H100 at **$3.50/hr** GPU price with reliability commitment **99%** and normal confidence (`sla_sigma_x = 0.5`). A client searches with **target 95%**. +**Setup:** You list an H100 at **$3.50/hr** GPU price with reliability commitment **99%** and **Medium** confidence (`sla_sigma_x = 0.5`). A client searches with **target 95%**. | Item | Amount | | --- | --- | @@ -748,7 +748,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ `sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints -ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). +**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. In scripts, pass `--retry 1` on `schedule maint` and `cancel maint`. A retried PUT can create a second window if the first one was stored and the response was lost. Confirm exactly one window before you schedule the next machine. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -789,7 +789,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Keep your own record of the exact `sla_sigma_x`.** `show machines` returns only the confidence band. It does return `credit_discount_max` while the machine is listed (`null` after unlist) and `min_bid_price` (your host-side minimum bid, net of the platform fee). The read-back can differ slightly from what you sent, so resend the `price_min_bid` you wrote down. Omitting it keeps the stored minimum. An offline machine drops out of `show machines` after about 10 hours (about 3 days with `include_offline=true`). Snapshot before you unlist. - 1. **Notify renters.** `echo y | vastai schedule maint MACHINE_ID --sdate "$(( $(date -u +%s) + 60 ))" --duration HOURS --maintenance_category other`. One minute ahead still counts as an unplanned window. See [Set a maintenance window](/host/set-maintenance-window). + 1. **Notify renters.** `echo y | vastai schedule maint MACHINE_ID --sdate "$(( $(date -u +%s) + 60 ))" --duration HOURS --maintenance_category other --retry 1`. Then `vastai show maints --ids 'MACHINE_ID' --raw` and confirm one window. One minute ahead still counts as an unplanned window. See [Set a maintenance window](/host/set-maintenance-window). 2. **Get your current terms before you unlist.** If the machine is still visible, save them now. If it is not, use your own notes. After unlist, `show machines` returns `null` for prices, `listed_min_gpu_count`, `end_date`, `credit_discount_max`, and SLA terms. The snapshot also omits hidden status (`hidden_listing`) and the exact `sla_sigma_x`. Write those down too. **Console:** Before you unlist, open **Set Pricing** and write down the GPU price, storage price, upload and download bandwidth prices, min GPU, end date (or auto-renew duration), whether the listing is hidden, **Reliability Commitment**, **Confidence** (**High**, **Medium**, or **Low**), the reserved discount, and the interruptible min bid. An omitted reserved discount on a new ask becomes `0.4`. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 52f7df2d..85a5e461 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current Claim and Confidence stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. +SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current **Reliability Commitment** (`sla_r_claim`) and **Confidence** stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. On an existing listing, omitted GPU price, bandwidth prices, reserved discount, and `end_date` are kept. diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 0adc1757..1bd46acf 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -65,7 +65,7 @@ If the machine must go offline without adequate notice, still run `schedule main vastai schedule maint MACHINE_ID --sdate "$(( $(date -u +%s) + 60 ))" --duration 1 --maintenance_category power ``` -To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine, and it asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID` and confirm the cancel succeeded with `vastai show maints -ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)) before you recreate windows. To reschedule, cancel first, then recreate each window you still want, as far ahead as you can. Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. +To cancel a scheduled window, use [`vastai cancel maint`](/host/cli/cancel-maint). That cancels **every** window you scheduled on the machine, and it asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID --retry 1` and confirm the cancel succeeded with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)) before you recreate windows. Pass `--retry 1` on `schedule maint` as well. A retried PUT can store a second window if the first response was lost. To reschedule, cancel first, then recreate each window you still want, as far ahead as you can. Across many machines, schedule sequentially at least 3 seconds apart (`sleep 3`; the endpoint's `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. ## Examples diff --git a/snippets/host/cli/show-maints.mdx b/snippets/host/cli/show-maints.mdx index ecc1d31e..ba2c8e65 100644 --- a/snippets/host/cli/show-maints.mdx +++ b/snippets/host/cli/show-maints.mdx @@ -5,13 +5,13 @@ Show maintenance information for host machines ## Usage ```bash -vastai show maints -ids 'machine_id_1' [OPTIONS] -vastai show maints -ids 'machine_id_1, machine_id_2' [OPTIONS] +vastai show maints --ids 'machine_id_1' [OPTIONS] +vastai show maints --ids 'machine_id_1,machine_id_2' [OPTIONS] ``` ## Options - + comma seperated string of machine_ids for which to get maintenance information diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index aea78ea9..37d5e718 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so Claim and Confidence stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. To keep auto-renew, pass `duration` again (seconds or a string such as `"30 days"`) on every call. Never pass `duration` together with `end_date`. Pass `min_chunk` as well. If you omit it, the SDK sends null and the server returns HTTP 400. The packaged CLI instead defaults `-m` to 1, which on a new ask splits the machine into single-GPU offers. `end_date` must be a Unix timestamp in seconds (`int` or `float`). Date strings such as `MM/DD/YYYY` are only converted by the CLI's `-e` flag. Update hidden SLA listings with REST and send `hidden_listing` explicitly. +SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so the **Reliability Commitment** (`sla_r_claim`) and **Confidence** stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. To keep auto-renew, pass `duration` again (seconds or a string such as `"30 days"`) on every call. Never pass `duration` together with `end_date`. Pass `min_chunk` as well. If you omit it, the SDK sends null and the server returns HTTP 400. The packaged CLI instead defaults `-m` to 1, which on a new ask splits the machine into single-GPU offers. `end_date` must be a Unix timestamp in seconds (`int` or `float`). Date strings such as `MM/DD/YYYY` are only converted by the CLI's `-e` flag. Update hidden SLA listings with REST and send `hidden_listing` explicitly. ## Signature From 2845b94a18f1b9690496346dd9cef82a879853de Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 03:04:27 -0700 Subject: [PATCH 211/250] docs(sla): address doc-review consensus (cycle 156) Document that plain-text 429s still send Retry-After, and abort a fleet re-list when SLA is off platform-wide. Co-authored-by: Cursor --- api-reference/openapi.yaml | 11 ++++---- .../openapi/yaml/create_instance.yaml | 2 +- api-reference/openapi/yaml/show_earnings.yaml | 2 +- .../openapi/yaml/show_instances.yaml | 2 +- api-reference/rate-limits-and-errors.mdx | 6 +++-- cli/rate-limits.mdx | 4 +-- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 6 ++--- guides/reference/billing.mdx | 6 ++--- guides/reference/faq/billing.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 9 ++++--- host/sla-offers.mdx | 25 ++++++++++++++----- sdk/python/rate-limits.mdx | 4 +-- 14 files changed, 50 insertions(+), 33 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index bed0e19f..ef786158 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1889,8 +1889,8 @@ paths: type: integer example: 1234567 '429': - description: Too Many Requests. Legacy limiter. Plain-text body, no Retry-After - header. `penalty` is not applied on this route. + description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* + headers are set. `penalty` is not applied on this route. content: text/plain: schema: @@ -8130,7 +8130,8 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. Plain-text body, no Retry-After header. + description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* + headers are set. content: text/plain: schema: @@ -8704,8 +8705,8 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. Legacy limiter. Plain-text body, no Retry-After - header. + description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* + headers are set. content: text/plain: schema: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 5ce90b01..c923804a 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -269,7 +269,7 @@ paths: type: integer example: 1234567 '429': - description: Too Many Requests. Legacy limiter. Plain-text body, no Retry-After header. `penalty` is not applied on this route. + description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* headers are set. `penalty` is not applied on this route. content: text/plain: schema: diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 2f9c969a..e02313e5 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -144,7 +144,7 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. Plain-text body, no Retry-After header. + description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* headers are set. content: text/plain: schema: diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index 2f5e84f8..7c7ae328 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -504,7 +504,7 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. Legacy limiter. Plain-text body, no Retry-After header. + description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* headers are set. content: text/plain: schema: diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index 1196bb4f..95342160 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -45,8 +45,10 @@ The combined API reference does not always show each operation's `x-rate-limit` When you hit a rate limit, you will receive **HTTP 429**. There are two families: -- **Legacy limiter** (plain text, no `Retry-After`): rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, listing `PUT /api/v0/machines/create_asks/`, and machine earnings `GET /api/v0/users/{user_id}/machine-earnings/`. The body looks like `API requests too frequent: endpoint threshold=…`. The rent route does not apply a penalty on top of that threshold. -- **Token-bucket limiter** (JSON plus a `Retry-After` header): search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`, the other earnings routes, schedule maintenance, and the SLA backtester. The body is `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}`. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- **Plain-text 429:** rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, listing `PUT /api/v0/machines/create_asks/`, and machine earnings `GET /api/v0/users/{user_id}/machine-earnings/`. The body looks like `API requests too frequent: endpoint threshold=…`. The rent route does not apply a penalty on top of that threshold. +- **JSON 429:** search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`, the other earnings routes, schedule maintenance, and the SLA backtester. The body is `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}`. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. + +Both kinds include a `Retry-After` header and `X-RateLimit-*` headers. Honor `Retry-After` when you see it. Branch on the body, not on whether the header is present. The CLI and SDK never read `Retry-After`. Honor `Retry-After` whenever it is present. If it is absent, wait at least that endpoint's pacing interval before the next call. diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 02df6ef5..42e9e684 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -33,8 +33,8 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Legacy rent, show-instances, `create_asks`, and `show earnings` (machine earnings) return plain text and no `Retry-After`. -- Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"` and a `Retry-After` header. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Rent, show-instances, `create_asks`, and `show earnings` (machine earnings) return a plain-text body. Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Both kinds include a `Retry-After` header. The CLI never reads it. The CLI never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 659c1d1b..58a97cc4 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -112,7 +112,7 @@ If you get this error when clicking the RENT button, the specific machine/GPU sl Startup time depends on the template and is usually under 5 minutes. If waiting over 20 minutes: - Ensure you're using a recommended template - Try a different machine -- Note: On a rental without an SLA, you're not charged while the instance is loading. Whether an SLA rental is billed during Loading is not specified. See [SLA](/guides/instances/choosing/sla-coverage). +- Note: On a rental without an SLA, you're not charged while the instance is loading. On an SLA rental, see [what you pay during an outage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - With slow internet and large images, downloads can take an hour or more If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy**. Destroy ends the rental and permanently deletes the instance and its disk, so copy off anything you need first. If you rented with an SLA, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 66e57001..3258acc1 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -291,7 +291,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta - **REST** (`GET /api/v1/instances/`): pass an explicit `limit` and page with `after_token` (the response `next_token`). If you omit `limit`, the server returns at most **25** rows. A non-positive `limit` is treated as 5, then capped at 25. - **CLI:** `vastai show instances --raw` fetches every page by default. `show instances-v1` is another name for the same command. Passing `--limit` (1–25) or `--next-token` switches to a single page. -**4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. Stopping it is not guaranteed to end the GPU charge or the SLA fee. Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. +**4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. On an SLA rental, see [Stop vs destroy](#what-you-pay-during-an-outage). Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. **Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Store the hourly SLA fee when the rent succeeds: `search.slaPremiumPerHour` on the `GET /api/v1/instances/` row for that contract. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. @@ -322,7 +322,7 @@ curl -s -G "https://console.vast.ai/api/v0/charges/" \ | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. After any retry, keep checking for the original label on your next few polls. If it appears later, destroy whichever instance you do not want. | -| Too many requests | HTTP 429. Search returns JSON. `error` is `HTTPTooManyRequests` for a short limit, or `search_quota_exceeded` when the daily row quota is used up. | If `error` is `search_quota_exceeded`, stop until `Retry-After` (it can be hours). Otherwise honor the short `Retry-After`. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. Rent 429s are plain text and have no `Retry-After`. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | +| Too many requests | HTTP 429. Search returns JSON. `error` is `HTTPTooManyRequests` for a short limit, or `search_quota_exceeded` when the daily row quota is used up. Rent 429s are plain text. Both include `Retry-After`. | If `error` is `search_quota_exceeded`, stop until `Retry-After` (it can be hours). Otherwise honor `Retry-After`. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | | CLI or SDK retried a rent on its own | The CLI and SDK retry connection errors, timeouts, and HTTP 429, 502, 503, and 504. They do not read `Retry-After`. They cannot set `target_reliability`. | For an SLA rent you send yourself, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | | Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | @@ -359,7 +359,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. -**Stop vs destroy.** Stopping an SLA rental is not guaranteed to end GPU or SLA charges. Budget as if billing continues until you **Destroy** the instance. Destroy deletes the disk. To see what a stopped SLA rental cost, check that instance's row in **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy** the instance. If your balance reaches $0 and you have no saved card, a stopped SLA instance can keep the balance negative while its data is scheduled for deletion. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. +**Stop vs destroy.** On an SLA rental, budget as if **Stop** does not end GPU or SLA charges. Only **Destroy** is guaranteed to end them, and Destroy deletes the disk. Check that instance's row in **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy** the instance. **Loading:** whether Loading time is billed on an SLA rental is not specified. Budget the wait as if it can be charged, and check **Charges** the next UTC day. If your balance reaches $0 and you have no saved card, a stopped SLA instance can keep the balance negative while its data is scheduled for deletion. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index a9927943..cea4ef9d 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -16,10 +16,10 @@ We accept credit card payments through Stripe and crypto payments through BitPay ### Negative Balances -Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. On an SLA rental, **Stop** is not guaranteed to end GPU or SLA charges. Budget as if billing continues until you **Destroy** the instance. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +Once your credits reach \$0.00, your instances, storage volumes, and data **will be scheduled for deletion** unless you add credits to make your balance positive again. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). **When your balance reaches zero (or below):** - - Your instances are **stopped automatically**. If you rent with an SLA, a stop at zero balance is not guaranteed to end the GPU charge or the SLA fee. Top up, or **Destroy** the instance if you need those charges to stop. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). + - Your instances are **stopped automatically**. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). Top up, or **Destroy** the instance if you need charges to stop. Destroy deletes the disk. - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. On an SLA rental, GPU and SLA fee charges may still continue while it is stopped (see the first bullet). If you have an SLA rental and no saved card, top up or **Destroy** the instance right away. Destroy deletes the disk. - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. - To protect accounts with established usage history, **the system allows a short grace period where your balance may go negative before deletion occurs** -- the length of this buffer is calculated based on your account's average daily spend. Accounts with higher historical spend receive a proportionally larger buffer. @@ -195,7 +195,7 @@ Before buying credit with Stripe you must add a card! ### Am I charged for "Loading" instances? -No, you are not charged when it says "Loading" on a rental without an SLA. Whether Loading time is billed on an SLA rental is not specified here. Budget the wait as if the rental can still be charging, and check **Charges** the next UTC day. +No, you are not charged when it says "Loading" on a rental without an SLA. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). ### What happens if my account balance is negative? diff --git a/guides/reference/faq/billing.mdx b/guides/reference/faq/billing.mdx index 52ab2970..df274d30 100644 --- a/guides/reference/faq/billing.mdx +++ b/guides/reference/faq/billing.mdx @@ -11,7 +11,7 @@ description: Questions about billing and credits Once you enter a credit card and an email address and both are verified you can then increase your credit balance using one-time payments with the add credit button. Whenever your credit balance hits zero or below, your instances will be stopped automatically, but not destroyed. -You are still charged storage costs for stopped instances, so it is important to destroy instances when you are done using them. On an SLA rental, a stop (including a stop at zero balance) is not guaranteed to end the GPU charge or the SLA fee. Top up, or destroy the instance if you need those charges to stop. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are still charged storage costs for stopped instances, so it is important to destroy instances when you are done using them. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). Your credit card will be automatically charged periodically to pay off any outstanding negative balance. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 256fbc3a..9bce8eef 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -252,7 +252,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. - **No SLA rentals:** Use this path only if SLA has never been on while any current rental was active. Otherwise use the SLA path below. Unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. -- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. It stops new rentals, and it also removes the SLA ask: after an unlist, `show machines` no longer returns your terms, so write them down first and re-enter **Reliability Commitment** and **Confidence** before you **LIST** ([Severe outage](/host/sla-offers#when-things-go-wrong)). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. If you unlist, write down every field on **Set Pricing** (GPU price, minimum GPUs, end date, storage, bandwidth, reserved discount, min bid, **Reliability Commitment**, and **Confidence**) and re-enter all of them before **LIST**. A blank bandwidth price publishes at $0. See [Severe outage](/host/sla-offers#when-things-go-wrong). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Pick the path that matches your situation: diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index fe68c721..f1dbf8f5 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -131,13 +131,14 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ Compare two confidence levels on the same history: ```bash -# Normal (default 0.6667) +# Medium (p=0.6667) curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.6667" -# Tight (0.83): lower SLA fees for renters, same credit rules +# Low (p=0.50): recommended start for a new or low-history machine. +# Renters pay a higher SLA fee. Credit rules are the same. curl -s -H "Authorization: Bearer YOUR_API_KEY" \ - "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.83" + "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.50" ``` ## Reading the response @@ -272,7 +273,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** ## Recommended workflow -1. **Run a baseline** on a machine with at least a few weeks of rental history, with `r_claim` set to the commitment you plan to list and `p=0.6667`. If `has_data` is `false`, widen the date range or wait for more history. Don't rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). +1. **Run a baseline** on a machine with at least a few weeks of rental history, with `r_claim` set to the commitment you plan to list and `p=0.6667` (Medium). For a new machine, also run `p=0.50` (Low), the recommended starting confidence. If `has_data` is `false`, widen the date range or wait for more history. Don't rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). 2. **Compare `r_eff` with `r_be`** to see whether you had headroom. 3. **Add `r_target`** at the targets renters are likely to choose (for example `0.95`) and compare `net_sla`. 4. **Check `largest_day_credit`** — can you absorb that from one bad day? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 5d0db4ad..468d0697 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -44,10 +44,11 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Reliability Commitment** and **Confidence**. In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. In the API, send `sla_r_claim` as a fraction (`0.99`, not `99`). With no history, start the commitment below the uptime you expect to deliver, and start **Confidence** at **Low** (wide margin). Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. If you enabled SLA through the API, run the confidence check in [Validation rules](#validation-rules) right away. -8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Search hides offers whose commitment is below the target. Confirm an **SLA Fee** line. If every offer is missing that line and `expected_reliability` even though you set a target, SLA may be off platform-wide. Search does not return an error in that case. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). +7. Enter **Reliability Commitment** and **Confidence**. In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. With no history, start the commitment below the uptime you expect to deliver, and start **Confidence** at **Low** (wide margin). Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. + - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). +8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Confirm an **SLA Fee** line. If that line is missing on every offer, SLA may be off platform-wide. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - - **Optional CLI/API:** search with `--storage` matching how renters quote; add `verified=any` if you search your own machine and see no rows (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). + - **API users:** search with `verified=any` and confirm `expected_reliability` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). ## Before you enable SLA @@ -438,7 +439,7 @@ For multiple machines, loop sequentially — do not parallelize without backoff: 1. Skip machines missing base pricing fields. 2. `PUT /api/v0/machines/create_asks/` with `machine` plus SLA fields (preserve existing reliability commitment and confidence when set). 3. Space requests at least 5 seconds apart (`sleep 5` in the example; `create_asks` has an `x-rate-limit` threshold of `5.0`). At fleet scale, detect HTTP **429** and retry that machine with backoff before treating it as failed—do not rerun the whole loop with `DRY_RUN=0` until transient rate limits clear. -4. On `invalid_sla_params`, `sla_not_approved`, `sla_disabled`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue or abort per your rollout policy. +4. On `invalid_sla_params`, `sla_not_approved`, `sla_daemon_outdated`, or `machine_locked`, log the machine ID and continue. The script aborts on `sla_disabled` and when a canary search finds no SLA offers at all. See [Fleet workflow](/host/sla-backtester#fleet-workflow) in the backtester for a similar sequential pattern. @@ -470,6 +471,14 @@ DRY_RUN="${DRY_RUN:-1}" if [ "$DRY_RUN" = "0" ] && [ -z "$ALLOWLIST" ]; then echo "abort: set ALLOWLIST to Listed machine IDs before DRY_RUN=0" >&2; exit 1 fi +# If no SLA offers exist marketplace-wide, SLA may be off. Do not re-list the fleet. +canary=$(vastai search offers 'has_sla=true verified=any' --limit 1 --raw --retry 1 --api-key "$SEARCH_API_KEY") \ + || { echo "Canary search failed; aborting." >&2; exit 1; } +if ! printf '%s' "$canary" | jq -e 'type == "array" and length > 0' >/dev/null; then + echo "No SLA offers marketplace-wide (SLA may be disabled). Aborting." >&2 + exit 1 +fi +sleep 6 machines=$(vastai show machines --raw --api-key "$VAST_API_KEY") for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then @@ -560,6 +569,10 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do echo "WARN machine_id=$id: re-list created a new ask; confirm bandwidth, credit_discount_max, price_min_bid, and confidence (a new ask defaults sla_sigma_x to 0.5)" >&2 fi else + if echo "$resp" | grep -q 'sla_disabled'; then + echo "SLA disabled platform-wide; stopping run." >&2 + exit 1 + fi echo "machine_id=$id error: $(echo "$resp" | jq -c '{success, error: (.error // .results[0].error), msg: (.msg // .results[0].msg)}' 2>/dev/null || echo "$resp")" fi sleep 5 @@ -802,7 +815,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep || echo "Snapshot is EMPTY: do not unlist yet" >&2 ``` - `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). That query parameter works on the server but is not listed in the API reference yet. If that `include_offline` response is also empty, use the console notes above. Do not unlist until you have the terms. + `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). If that `include_offline` response is also empty, use the console notes above. Do not unlist until you have the terms. 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. @@ -876,7 +889,7 @@ Weekly aggregates are window totals, not daily series — use a one-day range ab `GET /api/v0/users/me/machine-earnings/` returns SLA fields alongside compute earnings. The path user id is ignored; the account is the API key owner, so a **`billing_read`** key is enough (you do not need `user_read`). See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429 the body is plain text and there is no `Retry-After` header. Wait at least two seconds and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, pull one exact UTC day with `sday` and `eday` after UTC rollover. Do not use `last_days=1` for that job: it returns yesterday plus today so far. When a settled day stops changing is not documented; a later correction can change `sla_earn`. +This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429 the body is plain text. `Retry-After` is still set. Wait at least that long (otherwise at least two seconds) and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, pull one exact UTC day with `sday` and `eday` after UTC rollover. Do not use `last_days=1` for that job: it returns yesterday plus today so far. When a settled day stops changing is not documented; a later correction can change `sla_earn`. ```bash day=$(( $(date -u +%s) / 86400 - 1 )) diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 250771c7..74bb1099 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -35,8 +35,8 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Legacy rent, show-instances, `create_asks`, and machine earnings return plain text and no `Retry-After`. -- Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"` and a `Retry-After` header. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Rent, show-instances, `create_asks`, and machine earnings return a plain-text body. Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Both kinds include a `Retry-After` header. The SDK never reads it. The SDK never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. From 4f9592ac7930240a7cb9b71630d6dd72caa418c0 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 03:14:25 -0700 Subject: [PATCH 212/250] docs(sla): address doc-review consensus (cycle 157) Make show maints require --ids, and let the SDK search quote an SLA fee with a dict query. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 4 +- guides/instances/choosing/sla-coverage.mdx | 8 ++- guides/reference/faq/billing.mdx | 2 +- host/hosting-overview.mdx | 4 +- host/sla-backtester.mdx | 4 +- host/sla-offers.mdx | 4 +- sdk/python/reference/create-instance.mdx | 59 +++++++++++++++------- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/cli/show-maints.mdx | 6 +-- snippets/host/sdk/list-machine.mdx | 2 +- 10 files changed, 61 insertions(+), 34 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index a33fe819..4e81f8f0 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -187,7 +187,7 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability` (console or REST). The CLI and the Python SDK `search_offers()` cannot send `target_reliability`. Adding it to a query string returns HTTP 400. In CLI `--raw` output `search.slaPremiumPerHour` is 0 or absent and `dph_total` does not include an SLA fee. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. +**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability`. The CLI cannot send it: a query string becomes `{"eq": …}` and returns HTTP 400, so CLI `--raw` output has no SLA fee. The Python SDK can, if you pass a dict such as `search_offers(query={"has_sla": {"eq": True}, "target_reliability": 0.95})`. A string query fails the same way as the CLI. `search_offers()` cannot rent with SLA. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. | Field | Meaning | | --- | --- | @@ -196,7 +196,7 @@ bool = True | False | `expected_reliability` | Host reliability commitment (also a query key; see Available Fields) | -REST accepts `target_reliability` and returns `search.slaPremiumPerHour` for that quote. The CLI and the Python SDK `search_offers()` cannot. A CLI `target_reliability` filter is sent as an operator object and returns HTTP 400. Do not read an SLA fee from CLI `--raw` output. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance`) as in [SLA](/guides/instances/choosing/sla-coverage). +REST and the Python SDK (dict query only) accept `target_reliability` and return `search.slaPremiumPerHour` for that quote. The CLI cannot. A string `target_reliability` filter is sent as an operator object and returns HTTP 400. Do not read an SLA fee from CLI `--raw` output. Setting `target_reliability` in search does not enable the SLA at rent time; use console **Search filters → Reliability target** then **RENT**, or REST `PUT /api/v0/asks/{id}/` (not `vastai create instance` or `create_instance()`) as in [SLA](/guides/instances/choosing/sla-coverage). The same filters on `POST /api/v0/bundles/` use JSON operators. Match this shape from [SLA → API automation](/guides/instances/choosing/sla-coverage#api-automation): `"has_sla": {"eq": true}`, `"expected_reliability": {"gte": 0.99}`, `"target_reliability": 0.95` (a plain number; `{"eq": 0.95}` is rejected with 400). In that example `allocated_storage` is a number, not an operator object. The current CLI prints `Warning: Unrecognized field` for `has_sla` and `expected_reliability`. The warning is harmless: those fields are still sent. `target_reliability` is not in that harmless set. To self-check, run `--raw | jq 'all(.[]; .expected_reliability > 0)'` (CLI `--raw` prints a bare array of offers, not an `offers` object). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 3258acc1..e280f740 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -359,7 +359,13 @@ During an outage the Instances price popover may say "Machine is offline. You're **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. -**Stop vs destroy.** On an SLA rental, budget as if **Stop** does not end GPU or SLA charges. Only **Destroy** is guaranteed to end them, and Destroy deletes the disk. Check that instance's row in **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy** the instance. **Loading:** whether Loading time is billed on an SLA rental is not specified. Budget the wait as if it can be charged, and check **Charges** the next UTC day. If your balance reaches $0 and you have no saved card, a stopped SLA instance can keep the balance negative while its data is scheduled for deletion. Contact support before you count on a credit for downtime you caused yourself (your own Stop or reboot, a container crash, or a stop at zero balance). Whether that downtime counts against the host is not specified. Final SLA settlement still posts when the contract closes. +**Stop vs destroy.** + +- **Stop:** Budget as if **Stop** does not end GPU or SLA charges. Only **Destroy** ends the rental, and Destroy deletes the disk. Check **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy**. +- **Loading:** Budget as if Loading time on an SLA rental can be charged (GPU and SLA fee). Check **Charges** the next UTC day. +- **Zero balance:** At $0.00 a stopped SLA instance can keep the balance negative while its data is scheduled for deletion if you have no saved card. See [Negative Balances](/guides/reference/billing#negative-balances). +- **Downtime you cause:** Contact support before you count on a service credit for your own Stop or reboot, a bad image, a container crash, or a stop at zero balance. +- **Final settlement:** The net SLA row still posts when the contract closes. If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. diff --git a/guides/reference/faq/billing.mdx b/guides/reference/faq/billing.mdx index df274d30..87174023 100644 --- a/guides/reference/faq/billing.mdx +++ b/guides/reference/faq/billing.mdx @@ -9,7 +9,7 @@ description: Questions about billing and credits ### How does billing work? Once you enter a credit card and an email address and both are verified you can then increase your credit balance using one-time payments with the add credit button. -Whenever your credit balance hits zero or below, your instances will be stopped automatically, but not destroyed. +Whenever your credit balance hits zero or below, your instances are stopped and scheduled for deletion unless you add credit. Without a saved payment method, instances and their data are destroyed. See [Negative Balances](/guides/reference/billing#negative-balances). You are still charged storage costs for stopped instances, so it is important to destroy instances when you are done using them. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 9bce8eef..1d5ed868 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -203,7 +203,7 @@ It is vital to test your own machine to ensure the ports and software are runnin ### Set up a separate client account -There are two supported ways to test your own machine. If you want to use the website GUI, you will need to set up a new account on a different email address, add a credit card and then find your machine and create instances on it like a client. This has the benefit of showing you the entire client experience. Testing the recommended PyTorch template is vital to ensure that SSH and Jupyter are working properly. +There are two supported ways to test your own machine. If you want to use the website GUI, you will need to set up a new account on a different email address, add a credit card and then find your machine and create instances on it like a client. Include unverified machines in Search filters. New machines are usually unverified and are hidden by default. This has the benefit of showing you the entire client experience. Testing the recommended PyTorch template is vital to ensure that SSH and Jupyter are working properly. ### Use the CLI (preferred) @@ -251,7 +251,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **No SLA rentals:** Use this path only if SLA has never been on while any current rental was active. Otherwise use the SLA path below. Unlist so no new rentals start, then wait for current rentals to end. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. +- **No SLA rentals:** Use this path only if SLA has never been on while any current rental was active. Otherwise use the SLA path below. If you are not sure, schedule a window and keep the machine listed. Do not unlist. Unlist so no new rentals start, then wait for current rentals to end, only when you know SLA was never on. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. - **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. If you unlist, write down every field on **Set Pricing** (GPU price, minimum GPUs, end date, storage, bandwidth, reserved discount, min bid, **Reliability Commitment**, and **Confidence**) and re-enter all of them before **LIST**. A blank bandwidth price publishes at $0. See [Severe outage](/host/sla-offers#when-things-go-wrong). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Pick the path that matches your situation: diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index f1dbf8f5..9da17bfe 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -26,7 +26,7 @@ How much could SLA settlement cost given your reliability commitment and confide ## When to use it -Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. If `has_data` is `false`, widen the date range or pick a machine with more rental activity. +Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. History is usable from about mid-2026, when per-day rental active time started being recorded. Earlier days look idle. If `has_data` is `false`, move the window toward the present or pick a machine with more recent rental activity. Widening the window further into the past does not help. Use the backtester to: @@ -351,7 +351,7 @@ Expect about three seconds per machine (`sleep 3` plus request time), so budget ## When stuck -- **`has_data: false`** — Widen the date range or wait for rental history. +- **`has_data: false`** — Move the window toward the present, or wait for rental history. Widening it further into the past does not help. Days before about mid-2026 look idle. - **`400 bad_request` on a request that used to work** — Replace `r=` with `r_claim=` and remove `reliability=`. - **`401` / `403 auth_error` / `404 auth_error`** — Check that the `Authorization: Bearer` header is present, the key is complete (64 characters), and it has `machine_read`. - **Still stuck** — Ask in the [host Discord](https://discord.gg/hSuEbSQ4X8). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 468d0697..da53f226 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -132,7 +132,7 @@ Over many strong days, SLA fees can offset occasional credits, but a single bad SLA reliability is measured at the **rental contract (instance) level** using platform health signals for active on-demand contracts — not your personal SSH session or Jupyter tab. -- **Instance fails to start** because the machine is down (driver, disk, network, or daemon) → counts against SLA reliability for that contract. Whether downtime the renter causes (their own Stop or reboot, a bad image, a container crash, or a stop at zero balance) counts against you, or earns them a credit, is not specified. Contact support before you treat that downtime as yours. +- **Instance fails to start** because the machine is down (driver, disk, network, or daemon) → counts against SLA reliability for that contract. For downtime the renter causes (their own Stop or reboot, a bad image, a container crash, or a stop at zero balance), contact support before you treat it as yours or as a credit you owe. - **Machine-level outage** while contracts are active → affects settlement for those contracts. - **Brief host reboots** during active rentals may count as downtime. No fixed reboot-duration threshold applies. Treat any unplanned reboot as SLA risk. For planned work, use [Scheduled maintenance](#scheduled-maintenance). Notice is not a cutoff that removes the credit. - **Scheduled maintenance** may be partly forgiven (counted as uptime) — see [Scheduled maintenance](#scheduled-maintenance). That is not a service credit. @@ -524,7 +524,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do fi # A failed search must not become a PUT. Fully rented machines are also absent from search. sleep 6 - if ! out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --api-key "$SEARCH_API_KEY" 2>/dev/null); then + if ! out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --retry 1 --api-key "$SEARCH_API_KEY" 2>/dev/null); then echo "skip $id: search failed (missing misc permission or HTTP 429)" >&2 continue fi diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 7df49eb8..3bd1efd0 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -225,26 +225,47 @@ except requests.HTTPError as exc: resp = exc.response status = resp.status_code if resp is not None else 0 try: - body = resp.json() if resp is not None else {} + err_body = resp.json() if resp is not None else {} except ValueError: - body = {} - err = body.get("error", "") if isinstance(body, dict) else "" - msg = body.get("msg", "") if isinstance(body, dict) else "" - offer_gone = ( - status in (404, 410) - or err == "no_such_ask" - or err == "invalid_price" - or (err == "invalid_args" and "404/3603" in str(msg)) - ) - if offer_gone: - raise RuntimeError( - "Offer is gone or its price changed. Re-search and retry with a new offer id and a new label. Do not retry this offer id." - ) from exc - if status != 429 and 400 <= status < 500: - raise RuntimeError( - f"Rent failed ({status} {err}): {msg}. Fix the request or account. Do not retry this offer id." - ) from exc - contract_id = None + err_body = {} + err = err_body.get("error", "") if isinstance(err_body, dict) else "" + msg = err_body.get("msg", "") if isinstance(err_body, dict) else "" + if status == 429: + wait = 5 + if resp is not None: + try: + wait = max(float(resp.headers.get("Retry-After") or 0), 5) + except ValueError: + wait = 5 + time.sleep(wait) + rows = instances_for_label() + if rows: + contract_id = rows[0].get("id") + else: + response = requests.put( + f"https://console.vast.ai/api/v0/asks/{offer_id}/", + headers=headers, + json=body, + timeout=60, + ) + response.raise_for_status() + contract_id = response.json().get("new_contract") + else: + offer_gone = ( + status in (404, 410) + or err == "no_such_ask" + or err == "invalid_price" + or (err == "invalid_args" and "404/3603" in str(msg)) + ) + if offer_gone: + raise RuntimeError( + "Offer is gone or its price changed. Re-search and retry with a new offer id and a new label. Do not retry this offer id." + ) from exc + if 400 <= status < 500: + raise RuntimeError( + f"Rent failed ({status} {err}): {msg}. Fix the request or account. Do not retry this offer id." + ) from exc + contract_id = None except (requests.Timeout, requests.ConnectionError): contract_id = None diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 85a5e461..b2f29c50 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent. This is a **host** command, used for managing machines you are renting out on Vast.ai. -SLA listing flags are not in the published CLI yet — prefer console **Set Pricing → SLA**, or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current **Reliability Commitment** (`sla_r_claim`) and **Confidence** stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. +SLA listing flags are not on `vastai list machine`. Use the console (**Set Pricing → SLA**) or REST; see [SLA Offers](/host/sla-offers#api-for-automation). On a machine that is already listed with SLA, `vastai list machine` does not send SLA fields, so the current **Reliability Commitment** (`sla_r_claim`) and **Confidence** stay. After you unlist, a CLI relist creates a new ask **without** SLA. Turn it back on in **Set Pricing → SLA** or REST. On an existing listing, omitted GPU price, bandwidth prices, reserved discount, and `end_date` are kept. diff --git a/snippets/host/cli/show-maints.mdx b/snippets/host/cli/show-maints.mdx index ba2c8e65..844bef6d 100644 --- a/snippets/host/cli/show-maints.mdx +++ b/snippets/host/cli/show-maints.mdx @@ -11,8 +11,8 @@ vastai show maints --ids 'machine_id_1,machine_id_2' [OPTIONS] ## Options - - comma seperated string of machine_ids for which to get maintenance information + + Comma-separated machine IDs (required). Example: `'12345,12346'`. @@ -22,7 +22,7 @@ vastai show maints --ids 'machine_id_1,machine_id_2' [OPTIONS] ## Examples ```bash -vastai show maints +vastai show maints --ids '12345,12346' --raw ``` ## Global Options diff --git a/snippets/host/sdk/list-machine.mdx b/snippets/host/sdk/list-machine.mdx index 37d5e718..06d6cebe 100644 --- a/snippets/host/sdk/list-machine.mdx +++ b/snippets/host/sdk/list-machine.mdx @@ -3,7 +3,7 @@ Lists a machine for rent with optional pricing and configuration parameters. This is a **host** method, used for managing machines you are renting out on Vast.ai. -SLA listing parameters are not in the published Python SDK yet — use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so the **Reliability Commitment** (`sla_r_claim`) and **Confidence** stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. To keep auto-renew, pass `duration` again (seconds or a string such as `"30 days"`) on every call. Never pass `duration` together with `end_date`. Pass `min_chunk` as well. If you omit it, the SDK sends null and the server returns HTTP 400. The packaged CLI instead defaults `-m` to 1, which on a new ask splits the machine into single-GPU offers. `end_date` must be a Unix timestamp in seconds (`int` or `float`). Date strings such as `MM/DD/YYYY` are only converted by the CLI's `-e` flag. Update hidden SLA listings with REST and send `hidden_listing` explicitly. +`list_machine()` cannot set SLA fields. Use the console (**Set Pricing → SLA**) or REST `PUT /api/v0/machines/create_asks/` ([SLA Offers](/host/sla-offers#api-for-automation)). On an already-listed SLA machine, `list_machine()` does not send SLA fields, so the **Reliability Commitment** (`sla_r_claim`) and **Confidence** stay. After an unlist, a relist creates a new ask **without** SLA. `list_machine()` cannot send `hidden_listing`, so a reprice makes a hidden listing public. It also sends `vol_size` and `duration` as `null` unless you pass them: null `vol_size` can create a volume offer at half the free disk, and null `duration` clears auto-renew. Pass `vol_size=0` to skip a new volume offer. To keep auto-renew, pass `duration` again (seconds or a string such as `"30 days"`) on every call. Never pass `duration` together with `end_date`. Pass `min_chunk` as well. If you omit it, the SDK sends null and the server returns HTTP 400. The packaged CLI instead defaults `-m` to 1, which on a new ask splits the machine into single-GPU offers. `end_date` must be a Unix timestamp in seconds (`int` or `float`). Date strings such as `MM/DD/YYYY` are only converted by the CLI's `-e` flag. Update hidden SLA listings with REST and send `hidden_listing` explicitly. ## Signature From 50927a9914ae48506fa8a888bb8115e1ee06512e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 03:25:26 -0700 Subject: [PATCH 213/250] docs(sla): address doc-review consensus (cycle 158) Split the maintenance advice so it no longer says both unlist and do not unlist, and stop a failed label lookup from renting twice. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 6 ++--- host/hosting-overview.mdx | 8 ++++-- host/sla-backtester.mdx | 6 ++--- host/sla-offers.mdx | 8 +++--- sdk/python/reference/create-instance.mdx | 29 +++++++++++++++------- 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index e280f740..5d3f0706 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -273,7 +273,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ }' ``` -`template_hash_id` is the content hash of a saved template. Include `template_hash_id` to rent from the template. Add `image` only when you want to override the template image. A request needs at least one of those fields. A template rent can send `template_hash_id` alone. Request fields override template defaults. `disk` below 8 GB is raised to 8 GB with no error, so a CLI quote at the 5 GiB default will not match the billed storage. Rent returns `invalid_price` when the offer's GPU price exceeds the platform maximum, not because `target_reliability` changed. Re-search and use a fresh offer ID. See [Create Instance](/api-reference/instances/create-instance). +`template_hash_id` is the content hash of a saved template. Include `template_hash_id` to rent from the template. Add `image` only when you want to override the template image. A request needs at least one of those fields. A template rent can send `template_hash_id` alone. Request fields override template defaults. `disk` below 8 GB is raised to 8 GB with no error. Omitting `disk`, or sending `0`, rents 10 GB. A CLI quote at the 5 GiB default will not match the billed storage. Rent returns `invalid_price` when the offer's GPU price exceeds the platform maximum, not because `target_reliability` changed. Re-search and use a fresh offer ID. See [Create Instance](/api-reference/instances/create-instance). **API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Renter SLA scoped-key recipe](/api-reference/permissions#renter-sla-scoped-key-recipe). @@ -336,7 +336,7 @@ curl -s -G "https://console.vast.ai/api/v0/charges/" \ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** before REST rent, or match the **same integer** on the console disk slider and REST `"disk"`. Example: `vastai search offers --storage 50` → console slider **50** → `"disk": 50` on `PUT /api/v0/asks/{id}/`. -**Match disk size when comparing prices.** REST create-instance raises `disk` values below 8 GB to 8 GB without an error. Search and rent with the same number, 8 or more, so the quote matches the bill. CLI help labels `--storage` as GiB and REST labels `disk` as GB. Vast treats the same integer as the same quote. +**Match disk size when comparing prices.** REST create-instance raises `disk` values below 8 GB to 8 GB without an error. Omitting `disk`, or sending `0`, rents 10 GB. Search and rent with the same number, 8 or more, so the quote matches the bill. CLI help labels `--storage` as GiB and REST labels `disk` as GB. Vast treats the same integer as the same quote. ## What happens after you rent @@ -409,7 +409,7 @@ Production settlement uses the multi-window reliability blend described above, n ## If your instance goes down -1. If you can still reach the instance, save work. If the machine is offline, you may not be able to copy data off it. You can wait (compute, storage, and the SLA fee keep billing; a credit applies only if that day's blended measure falls below your target) or **Destroy** (charges stop and the disk is deleted). Check **Instances** for host or maintenance status. +1. Turn on **Instance offline** and **Instance back online** ([Notifications](/guides/reference/notifications)) so you can decide quickly whether to wait or **Destroy**. If you can still reach the instance, save work. If the machine is offline, you may not be able to copy data off it. You can wait (compute, storage, and the SLA fee keep billing; a credit applies only if that day's blended measure falls below your target) or **Destroy** (charges stop and the disk is deleted). Check **Instances** for host or maintenance status. 2. Remember: compute, storage, and SLA fees continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. 3. **Console:** Open **Instances**, select the instance, then **Destroy** to end charges on an unavailable SLA instance. See [Stop vs destroy](#what-you-pay-during-an-outage). Destroy deletes the disk, so copy off anything you need first. 4. After the UTC day settles, check **Account → Billing → Charges** or `GET /api/v0/charges/` for the net SLA row. Invoices do not show SLA credits. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 1d5ed868..aa9dd845 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -251,12 +251,16 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **No SLA rentals:** Use this path only if SLA has never been on while any current rental was active. Otherwise use the SLA path below. If you are not sure, schedule a window and keep the machine listed. Do not unlist. Unlist so no new rentals start, then wait for current rentals to end, only when you know SLA was never on. Do not move the offer end date to prepare for maintenance: any end date you send extends every active rental that ends before it. +- **If you are sure SLA was never on during any current rental:** unlist so no new rentals start, then wait for those rentals to end before you take the machine offline. +- **If you are not sure:** do not unlist. Keep the machine listed and schedule a maintenance window (the SLA path below). + +Do not move the offer end date to prepare for maintenance. Any end date you send extends every active rental that ends before it. + - **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. If you unlist, write down every field on **Set Pricing** (GPU price, minimum GPUs, end date, storage, bandwidth, reserved discount, min bid, **Reliability Commitment**, and **Confidence**) and re-enter all of them before **LIST**. A blank bandwidth price publishes at $0. See [Severe outage](/host/sla-offers#when-things-go-wrong). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Pick the path that matches your situation: -1. **Preferred (no active renters):** Wait until all contracts have ended, then take the machine offline. +1. **Preferred:** Wait until all active contracts have ended (or the machine has none), then take it offline. 2. **Planned downtime with active renters:** Schedule as far ahead as you can from the console or with [`vastai schedule maint`](/host/cli/schedule-maint). See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). 3. **Emergency or unplanned downtime:** Notify renters immediately, either from the console ([Set a maintenance window](/host/set-maintenance-window)) or with [`vastai schedule maint`](/host/cli/schedule-maint). Use one path per window. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 9da17bfe..34ee9a70 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -143,7 +143,7 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ ## Reading the response -**If you only read three things:** check `has_data` (widen dates if `false`), compare `r_eff` with `r_be`, then look at your [net SLA result and largest single-day credit](#summarize-with-jq). +**If you only read three things:** check `has_data` (if `false`, move the window toward the present or wait for more rental history), compare `r_eff` with `r_be`, then look at your [net SLA result and largest single-day credit](#summarize-with-jq). A successful response looks like this (one `days` row shown; values are illustrative): @@ -179,7 +179,7 @@ A successful response looks like this (one `days` row shown; values are illustra | Field | Meaning | | --- | --- | -| `has_data` | `true` if the range had at least one day of rental earnings to replay. When `false`, every `days` row is zero with `reliability: null`, and `r_eff` is `null`. Try a wider window or a machine with more rental history. | +| `has_data` | `true` if the range had at least one day of rental activity to replay. `false` means no usable history in the window. Move the window toward the present (days before about mid-2026 look idle) or wait for more rental history. When `false`, every `days` row is zero with `reliability: null`, and `r_eff` is `null`. | | `start_day`, `end_day` | UTC day indices, `day = floor(epoch_seconds / 86400)`. `day × 86400` is exactly 00:00 UTC on that date. Convert with `date -u -d "@$((day * 86400))" +%F` (Linux) or `date -u -r $((day * 86400)) +%F` (macOS). Show Earnings `sday` / `eday` use the same day index. | | `r_eff` | **Effective reliability**: the constant reliability that would have produced the service credits paid in this window. `null` when nothing was paid into escrow in the window (all `client_*_to_escrow` values are zero, as with `has_data: false`). | | `r_be` | **Break-even reliability**: the reliability at which SLA fees and service credits cancel out. Always present. | @@ -273,7 +273,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** ## Recommended workflow -1. **Run a baseline** on a machine with at least a few weeks of rental history, with `r_claim` set to the commitment you plan to list and `p=0.6667` (Medium). For a new machine, also run `p=0.50` (Low), the recommended starting confidence. If `has_data` is `false`, widen the date range or wait for more history. Don't rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). +1. **Run a baseline** on a machine with at least a few weeks of rental history, with `r_claim` set to the commitment you plan to list and `p=0.6667` (Medium). For a new machine, also run `p=0.50` (Low), the recommended starting confidence. If `has_data` is `false`, move the date range toward the present or wait for more history. Don't rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). 2. **Compare `r_eff` with `r_be`** to see whether you had headroom. 3. **Add `r_target`** at the targets renters are likely to choose (for example `0.95`) and compare `net_sla`. 4. **Check `largest_day_credit`** — can you absorb that from one bad day? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index da53f226..530b44fd 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -43,7 +43,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. -6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. +6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. Enter **Reliability Commitment** and **Confidence**. In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. With no history, start the commitment below the uptime you expect to deliver, and start **Confidence** at **Low** (wide margin). Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Confirm an **SLA Fee** line. If that line is missing on every offer, SLA may be off platform-wide. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). @@ -448,6 +448,8 @@ This example is illustrative: it sleeps between machines and logs success/error ```bash : "${VAST_API_KEY:?export VAST_API_KEY first (needs machine_write and machine_read)}" : "${SEARCH_API_KEY:?export SEARCH_API_KEY first (needs misc, on its own key)}" +# Do not reuse this loop to change SLA terms on machines that have rentals. +# It resends end_date or duration, which extends every shorter active contract. # Leave DRY_RUN=1 until you confirm each machine is **Listed** (or on your allowlist). # Set DRY_RUN=0 to apply. # ALLOWLIST required for DRY_RUN=0 (space-separated listed machine IDs). @@ -579,7 +581,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `show machines` returns `min_bid_price` (your host-side minimum bid, net of the platform fee, same idea as `listed_gpu_cost`). The value you read back can differ slightly from what you sent. Resend the `price_min_bid` you wrote down if you need to change it. On an existing ask, omitting it keeps the stored minimum. After an unlist, resend it: do not rely on the stored value. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `show machines` returns `min_bid_price` (your host-side minimum bid, net of the platform fee, same idea as `listed_gpu_cost`). The value you read back can differ slightly from what you sent. Resend the `price_min_bid` you wrote down if you need to change it. On an existing ask, omitting it keeps the stored minimum. After an unlist, resend it: do not rely on the stored value. On an existing ask, a bandwidth price of `0` or a storage price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. @@ -844,7 +846,7 @@ After you enable SLA, charges and credits settle on UTC (Coordinated Universal T **If the daily total looks wrong:** widen the date range (settlement uses UTC day boundaries), confirm the machine had an active on-demand rental that day, and confirm SLA was enabled and the offer was **listed** (not just saved). There is still no separate SLA row on the normal Host → Billing view. -SLA settlement does not currently emit host webhooks. Monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. +SLA settlement does not emit a host webhook. Machine offline and error alerts do ([Host Notifications](/host/notifications)). Subscribe to `host:machine_offline` so you can start the outage steps right away. Otherwise monitor via console billing or poll `machine-earnings`; settlements align to UTC calendar days. ### CLI diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 3bd1efd0..b765f4ea 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -209,9 +209,13 @@ def instances_for_label(): ) found.raise_for_status() except requests.RequestException: - return [] + return None return found.json().get("instances") or [] +already = instances_for_label() +if already is None or already: + raise SystemExit("Label lookup failed, or this label already has an instance. Do not PUT.") + try: response = requests.put( f"https://console.vast.ai/api/v0/asks/{offer_id}/", @@ -239,17 +243,24 @@ except requests.HTTPError as exc: wait = 5 time.sleep(wait) rows = instances_for_label() + if rows is None: + raise RuntimeError( + "Label lookup failed. Do not PUT again until you have checked Instances." + ) from exc if rows: contract_id = rows[0].get("id") else: - response = requests.put( - f"https://console.vast.ai/api/v0/asks/{offer_id}/", - headers=headers, - json=body, - timeout=60, - ) - response.raise_for_status() - contract_id = response.json().get("new_contract") + try: + response = requests.put( + f"https://console.vast.ai/api/v0/asks/{offer_id}/", + headers=headers, + json=body, + timeout=60, + ) + response.raise_for_status() + contract_id = response.json().get("new_contract") + except (requests.Timeout, requests.ConnectionError, requests.HTTPError): + contract_id = None else: offer_gone = ( status in (404, 410) From c54092dbf9a02414068ad810c36eed3032fcc91f Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 03:37:31 -0700 Subject: [PATCH 214/250] docs(sla): address doc-review consensus (cycle 159) Stop telling hosts to PUT read-side field names, and detect legacy 429s by status instead of a plain-text body. Co-authored-by: Cursor --- api-reference/openapi.yaml | 21 +++++++++++-------- .../openapi/yaml/create_instance.yaml | 4 ++-- api-reference/openapi/yaml/show_earnings.yaml | 4 ++-- .../openapi/yaml/show_instances.yaml | 4 ++-- api-reference/rate-limits-and-errors.mdx | 4 ++-- cli/rate-limits.mdx | 4 ++-- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 7 +++---- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 12 +++++------ sdk/python/rate-limits.mdx | 4 ++-- 11 files changed, 35 insertions(+), 33 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index ef786158..3fafaa01 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1889,10 +1889,11 @@ paths: type: integer example: 1234567 '429': - description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* - headers are set. `penalty` is not applied on this route. + description: Too Many Requests. Body follows the Accept header (usually + HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers + are set. `penalty` is not applied on this route. content: - text/plain: + text/html: schema: type: string example: 'API requests too frequent: endpoint threshold=4.5*1' @@ -8130,10 +8131,11 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* - headers are set. + description: Too Many Requests. Body follows the Accept header (usually + HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers + are set. content: - text/plain: + text/html: schema: type: string example: 'API requests too frequent: endpoint threshold=2*1' @@ -8705,10 +8707,11 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* - headers are set. + description: Too Many Requests. Body follows the Accept header (usually + HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers + are set. content: - text/plain: + text/html: schema: type: string example: 'API requests too frequent: endpoint threshold=1.0*1' diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index c923804a..523adc8c 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -269,9 +269,9 @@ paths: type: integer example: 1234567 '429': - description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* headers are set. `penalty` is not applied on this route. + description: Too Many Requests. Body follows the Accept header (usually HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers are set. `penalty` is not applied on this route. content: - text/plain: + text/html: schema: type: string example: "API requests too frequent: endpoint threshold=4.5*1" diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index e02313e5..0734088c 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -144,9 +144,9 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* headers are set. + description: Too Many Requests. Body follows the Accept header (usually HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers are set. content: - text/plain: + text/html: schema: type: string example: "API requests too frequent: endpoint threshold=2*1" diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index 7c7ae328..d421764a 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -504,9 +504,9 @@ paths: schema: $ref: '#/components/schemas/Error' '429': - description: Too Many Requests. Plain-text body. Retry-After and X-RateLimit-* headers are set. + description: Too Many Requests. Body follows the Accept header (usually HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers are set. content: - text/plain: + text/html: schema: type: string example: "API requests too frequent: endpoint threshold=1.0*1" diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index 95342160..b481e3df 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -45,10 +45,10 @@ The combined API reference does not always show each operation's `x-rate-limit` When you hit a rate limit, you will receive **HTTP 429**. There are two families: -- **Plain-text 429:** rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, listing `PUT /api/v0/machines/create_asks/`, and machine earnings `GET /api/v0/users/{user_id}/machine-earnings/`. The body looks like `API requests too frequent: endpoint threshold=…`. The rent route does not apply a penalty on top of that threshold. +- **Legacy-limited routes** (rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, listing `PUT /api/v0/machines/create_asks/`, and machine earnings `GET /api/v0/users/{user_id}/machine-earnings/`): the body is not the JSON `{"error": …}` shape. With the default `Accept: */*` (curl, `requests`) it is usually an HTML page. With `Accept: application/json` it is a generic JSON error. Detect the limit by HTTP status 429 and `Retry-After`. The rent route does not apply a penalty on top of that threshold. - **JSON 429:** search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`, the other earnings routes, schedule maintenance, and the SLA backtester. The body is `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}`. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. -Both kinds include a `Retry-After` header and `X-RateLimit-*` headers. Honor `Retry-After` when you see it. Branch on the body, not on whether the header is present. The CLI and SDK never read `Retry-After`. +Both kinds include a `Retry-After` header and `X-RateLimit-*` headers. Honor `Retry-After` when you see it. The CLI and SDK never read `Retry-After`. Honor `Retry-After` whenever it is present. If it is absent, wait at least that endpoint's pacing interval before the next call. diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 42e9e684..47036e48 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -33,8 +33,8 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Rent, show-instances, `create_asks`, and `show earnings` (machine earnings) return a plain-text body. Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. -- Both kinds include a `Retry-After` header. The CLI never reads it. +- Rent, show-instances, `create_asks`, and `show earnings` (machine earnings) do not return the JSON `{"error": …}` body. With a default Accept header the body is usually HTML. Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Both kinds include a `Retry-After` header. Detect a limit by HTTP status 429. The CLI never reads `Retry-After`. The CLI never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 58a97cc4..2f07c5db 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA Fee** line in the price breakdown. An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -The console and REST search quote SLA-inclusive prices. The CLI can only find SLA offers; its `dph_total` excludes the SLA fee. None of them turn SLA on. If you searched via CLI or API, set **Reliability target** in the console **Search filters** before **RENT**. CLI/API search query settings do not carry over when you switch to the web console. Console Search filters (including **Reliability target**) apply to that console session before **RENT**. If the price breakdown has no **SLA Fee** line, you do not have an SLA. If that line is missing on every offer after you set a **Reliability target**, SLA may be off platform-wide (search does not return an error). Contact support. SLA rent requires the console or REST—see [CLI cannot set `target_reliability`](/cli/reference/create-instance#sla). +To rent with an SLA, set **Reliability target** in **Search filters** (left bar), confirm the price breakdown shows an **SLA Fee** line, then click **RENT**. No **SLA Fee** line means no SLA. If that line is missing on every offer, contact support. CLI/API query settings do not carry over into the console. For CLI and API limits, see [SLA](/guides/instances/choosing/sla-coverage). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 5d3f0706..04d71dea 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -298,7 +298,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta 1. Call Show Charges for one UTC day. `day.gte` and `day.lte` are both required (unix seconds). Set `day.lte` to `day.gte + 86399`. 2. Page with `after_token` / `next_token` until `next_token` is `null`. Space calls about one second apart. 3. Find the row whose `source` is `instance-` plus the contract id from `new_contract`, then the `items[]` entry with `type: "sla"`. -4. Compare that amount with the stored hourly fee times the hours the contract was active that day, including downtime. A smaller or negative amount means a credit was applied. How the console labels the row is in [Settlement timing](#settlement-timing). +4. Compare that amount with the stored hourly fee times the hours the contract was active that day. A smaller or negative amount usually means a credit was applied. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. How the console labels the row is in [Settlement timing](#settlement-timing). The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. If `next_token` is not `null`, repeat the request with `after_token` set to that value before you treat a missing `sla` item as unsettled. `limit` defaults to 100, so a busy account can put the contract on a later page. @@ -322,7 +322,7 @@ curl -s -G "https://console.vast.ai/api/v0/charges/" \ | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. After any retry, keep checking for the original label on your next few polls. If it appears later, destroy whichever instance you do not want. | -| Too many requests | HTTP 429. Search returns JSON. `error` is `HTTPTooManyRequests` for a short limit, or `search_quota_exceeded` when the daily row quota is used up. Rent 429s are plain text. Both include `Retry-After`. | If `error` is `search_quota_exceeded`, stop until `Retry-After` (it can be hours). Otherwise honor `Retry-After`. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | +| Too many requests | HTTP 429. Search returns JSON. `error` is `HTTPTooManyRequests` for a short limit, or `search_quota_exceeded` when the daily row quota is used up. Rent 429s are not that JSON shape (usually an HTML page). Both include `Retry-After`. | If `error` is `search_quota_exceeded`, stop until `Retry-After` (it can be hours). Otherwise honor `Retry-After`. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | | CLI or SDK retried a rent on its own | The CLI and SDK retry connection errors, timeouts, and HTTP 429, 502, 503, and 504. They do not read `Retry-After`. They cannot set `target_reliability`. | For an SLA rent you send yourself, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | | Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | | Missing SSH key for the VM | HTTP 400 `no_ssh_key_for_vm` (or similar) | Add an SSH key on your account before renting, then retry with a current offer id. | @@ -361,8 +361,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **Stop vs destroy.** -- **Stop:** Budget as if **Stop** does not end GPU or SLA charges. Only **Destroy** ends the rental, and Destroy deletes the disk. Check **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy**. -- **Loading:** Budget as if Loading time on an SLA rental can be charged (GPU and SLA fee). Check **Charges** the next UTC day. +- **Stop:** How **Stop** and **Loading** time are billed on an SLA rental is not guaranteed. Budget as if both can still be charged. Only **Destroy** reliably ends GPU and SLA charges, and Destroy deletes the disk. Check **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy**. - **Zero balance:** At $0.00 a stopped SLA instance can keep the balance negative while its data is scheduled for deletion if you have no saved card. See [Negative Balances](/guides/reference/billing#negative-balances). - **Downtime you cause:** Contact support before you count on a service credit for your own Stop or reboot, a bad image, a container crash, or a stop at zero balance. - **Final settlement:** The net SLA row still posts when the contract closes. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index aa9dd845..5618db90 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -256,7 +256,7 @@ Unlisting the offer prevents new rentals but does not end existing ones. Do not move the offer end date to prepare for maintenance. Any end date you send extends every active rental that ends before it. -- **SLA rentals:** For a short planned window, keep the machine listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlisting is optional. If you unlist, write down every field on **Set Pricing** (GPU price, minimum GPUs, end date, storage, bandwidth, reserved discount, min bid, **Reliability Commitment**, and **Confidence**) and re-enter all of them before **LIST**. A blank bandwidth price publishes at $0. See [Severe outage](/host/sla-offers#when-things-go-wrong). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **SLA rentals:** Stay listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlist only if you are sure SLA was never on during a current rental. If you do unlist, write down every field on **Set Pricing** first (GPU price, minimum GPUs, end date, storage, bandwidth, reserved discount, min bid, **Reliability Commitment**, and **Confidence**) and re-enter all of them before **LIST**. A blank bandwidth price publishes at $0. See [Severe outage](/host/sla-offers#when-things-go-wrong). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Pick the path that matches your situation: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 530b44fd..cde031b2 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -306,10 +306,10 @@ Some omitted fields reset to defaults (for example `price_disk`, `hidden_listing curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"machine": 12345, "price_disk": CURRENT_STORAGE_PRICE, "price_inetu": CURRENT_INET_UP, "price_inetd": CURRENT_INET_DOWN, "credit_discount_max": CURRENT_DISCOUNT, "price_min_bid": CURRENT_MIN_BID, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' + -d '{"machine": 12345, "price_disk": CURRENT_STORAGE_PRICE, "price_inetu": CURRENT_INET_UP, "price_inetd": CURRENT_INET_DOWN, "credit_discount_max": CURRENT_DISCOUNT, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `CURRENT_STORAGE_PRICE`, `CURRENT_INET_UP`, `CURRENT_INET_DOWN`, `CURRENT_DISCOUNT`, `CURRENT_MIN_BID`, and `CURRENT_MIN_CHUNK` from `vastai show machines --raw` (`listed_storage_cost`, `listed_inet_up_cost`, `listed_inet_down_cost`, `credit_discount_max`, `min_bid_price`, and `listed_min_gpu_count`). `min_bid_price` is host-side, net of the platform fee. `show machines` does not report hidden status. Set `CURRENT_HIDDEN` from your own notes or **Set Pricing**. Sending `false` for a hidden listing makes it public. An unedited paste is not valid JSON. Include bandwidth, discount, and min bid in the body so a new ask does not publish at $0 bandwidth or the 0.4 discount default. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Check those fields in the response. Send `end_date` only in the full listing update below, when you mean to extend. +Replace `CURRENT_STORAGE_PRICE`, `CURRENT_INET_UP`, `CURRENT_INET_DOWN`, `CURRENT_DISCOUNT`, and `CURRENT_MIN_CHUNK` from `vastai show machines --raw` (`listed_storage_cost`, `listed_inet_up_cost`, `listed_inet_down_cost`, `credit_discount_max`, and `listed_min_gpu_count`). On an existing ask, omit `price_min_bid`. The stored minimum is kept. Do not copy `min_bid_price` into the body. That value is net of the platform fee, and resending it shifts the minimum on every update. After an unlist, send the `price_min_bid` you wrote down yourself. `show machines` does not report hidden status. Set `CURRENT_HIDDEN` from your own notes or **Set Pricing**. Sending `false` for a hidden listing makes it public. An unedited paste is not valid JSON. Include bandwidth and the discount in the body so a new ask does not publish at $0 bandwidth or the 0.4 discount default. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Check those fields in the response. Send `end_date` only in the full listing update below, when you mean to extend. Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes the reliability commitment or Confidence in a way that would raise that contract's SLA fee. A reliability-commitment or Confidence change does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). @@ -376,9 +376,9 @@ This creates an offer with a reliability commitment of `0.99` and confidence spr - `price_disk` resets to **$0.10/GB/month** if omitted or `null`. - `duration` is cleared if omitted (a listing created with `vastai list machine -l` stops auto-renewing, and nothing is extended). Sending integer `duration` keeps auto-renew on and extends every shorter rental, including SLA rentals. There is no way to change the reliability commitment or Confidence on a rolling listing while keeping auto-renew on and not extending rentals. - `hidden_listing` resets to `false` if omitted (a hidden listing becomes visible). `show machines` does not return this flag, so send `true` when the listing should stay hidden. -- `min_chunk` defaults to **1** when offers are created or re-created (first publish, or relisting after an unlist). On an already-listed machine, omitting it does not change the current minimum. Still send `listed_min_gpu_count` so a later relist does not slice the machine by accident. +- `min_chunk` defaults to **1** when offers are created or re-created (first publish, or relisting after an unlist). On an already-listed machine, omitting it does not change the current minimum. Still send `min_chunk` (read it from `listed_min_gpu_count`) so a later relist does not slice the machine by accident. - `vol_size` omitted on a machine with no volume offer creates one sized at half the free disk. Send `"vol_size": 0` to keep that from happening. `0` does not delete a volume offer that already exists. -- On a **new** ask (first publish, or a new offer after unlist), omitted `price_inetu` and `price_inetd` become `0` (free bandwidth) and omitted `credit_discount_max` becomes `0.4`. Updating an existing ask keeps those values when they are omitted. Send `listed_inet_up_cost`, `listed_inet_down_cost`, and `credit_discount_max` when you create the offer. +- On a **new** ask (first publish, or a new offer after unlist), omitted `price_inetu` and `price_inetd` become `0` (free bandwidth) and omitted `credit_discount_max` becomes `0.4`. Updating an existing ask keeps those values when they are omitted. Send `price_inetu`, `price_inetd`, and `credit_discount_max` when you create the offer (read them from `listed_inet_up_cost`, `listed_inet_down_cost`, and `credit_discount_max`). - Send **either** `duration` (integer seconds; a float such as `2592000.0` returns 400 `Invalid duration`) **or** `end_date`, never both. Sending both returns `400` `Cannot set both duration and end_date`. Always read the current listing and send `price_disk`. To change the reliability commitment or Confidence on a rented machine **without** extending rentals, omit both `duration` and `end_date`. The stored end date stays, and no contract is extended. Omitting `duration` on a rolling listing turns auto-renew off. Send `duration` (integer seconds) or `end_date` only when you mean to keep auto-renew or to extend. Map read-side names as follows: `listed_gpu_cost` → `price_gpu`, `listed_storage_cost` → `price_disk`. @@ -581,7 +581,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `show machines` returns `min_bid_price` (your host-side minimum bid, net of the platform fee, same idea as `listed_gpu_cost`). The value you read back can differ slightly from what you sent. Resend the `price_min_bid` you wrote down if you need to change it. On an existing ask, omitting it keeps the stored minimum. After an unlist, resend it: do not rely on the stored value. On an existing ask, a bandwidth price of `0` or a storage price of `0` is treated as omitted and the old price is kept. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `show machines` returns `min_bid_price` (your host-side minimum bid, net of the platform fee, same idea as `listed_gpu_cost`). The value you read back can differ slightly from what you sent. Resend the `price_min_bid` you wrote down if you need to change it. On an existing ask, omitting it keeps the stored minimum. After an unlist, resend it: do not rely on the stored value. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. A storage price of `0` also keeps the stored price. Omitting `price_disk` is different: it resets storage to $0.10. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. @@ -891,7 +891,7 @@ Weekly aggregates are window totals, not daily series — use a one-day range ab `GET /api/v0/users/me/machine-earnings/` returns SLA fields alongside compute earnings. The path user id is ignored; the account is the API key owner, so a **`billing_read`** key is enough (you do not need `user_read`). See [`show earnings`](/api-reference/billing/show-earnings). -This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429 the body is plain text. `Retry-After` is still set. Wait at least that long (otherwise at least two seconds) and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, pull one exact UTC day with `sday` and `eday` after UTC rollover. Do not use `last_days=1` for that job: it returns yesterday plus today so far. When a settled day stops changing is not documented; a later correction can change `sla_earn`. +This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at most about once every two seconds as a safe default (OpenAPI `x-rate-limit` threshold `2.0` on [Show Earnings](/api-reference/billing/show-earnings)). On HTTP 429, detect the limit by the status code. The body is not the JSON `{"error": …}` shape. `Retry-After` is still set. Wait at least that long (otherwise at least two seconds) and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). For daily SLA settlement, pull one exact UTC day with `sday` and `eday` after UTC rollover. Do not use `last_days=1` for that job: it returns yesterday plus today so far. When a settled day stops changing is not documented; a later correction can change `sla_earn`. ```bash day=$(( $(date -u +%s) / 86400 - 1 )) diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 74bb1099..73f094f3 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -35,8 +35,8 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Rent, show-instances, `create_asks`, and machine earnings return a plain-text body. Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. -- Both kinds include a `Retry-After` header. The SDK never reads it. +- Rent, show-instances, `create_asks`, and machine earnings do not return the JSON `{"error": …}` body. With a default Accept header the body is usually HTML. Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Both kinds include a `Retry-After` header. Detect a limit by HTTP status 429. The SDK never reads `Retry-After`. The SDK never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. From 87f1f6f9f6bf0d8b37f30504832925afb68d9c99 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 03:48:58 -0700 Subject: [PATCH 215/250] docs(sla): address doc-review consensus (cycle 160) Align unlist and locked-term wording, and stop existing-ask examples from resending the fee-adjusted min bid. Co-authored-by: Cursor --- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 12 +++++++++++- host/hosting-overview.mdx | 10 +++------- host/sla-backtester.mdx | 1 + host/sla-offers.mdx | 12 +++++++----- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 2f07c5db..79d6690c 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -19,7 +19,7 @@ You will find various search options on the top and left control bars that allow ## Offer card -The offer card shows the details of a machine available for rent, including specs, pricing, and the maximum rental duration. When you rent an instance, a rental contract is created between you and the host based on the offer's current terms. The offer remains available for other clients until it reaches its end date or is unlisted by the host. +The offer card shows the details of a machine available for rent, including specs, pricing, and the maximum rental duration. When you rent an instance, a rental contract is created between you and the host based on the offer's current terms. Once you rent, those GPUs are yours for the length of the contract. The host's listing may keep offering the machine's remaining GPUs to other renters until its end date or until the host unlists it. Most of the items on the offer card can be filtered using the search filters. Some of the important parts are the price and the maximum rental duration. Hovering over the price shows the different prices for GPU rental, storage, and bandwidth. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 04d71dea..2d4cb25f 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -313,6 +313,16 @@ curl -s -G "https://console.vast.ai/api/v0/charges/" \ **Automation limitations:** SLA credits are not sent as webhooks and do not appear on invoices. Read Charges after settlement (see [Settlement timing](#settlement-timing)). After the UTC day boundary (wait up to about 48 hours if a line is missing), check that row or contact support. Verify an active SLA on instances with `GET /api/v1/instances/`. Confirm `target_reliability > 0`. A present but zero value means the rental has no SLA. Also check `instance.slaPremiumPerHour` once the instance is running. Show-instances uses OpenAPI threshold `1.0` (about one request per second). +#### If the rent outcome is unknown + +A timeout, a dropped connection, or HTTP 5xx means the rental may already exist. There is no idempotency key. + +1. Do not send the PUT again yet. +2. Look up your unique `label` with `GET /api/v1/instances/` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`), a few times about a second apart (Show Instances threshold `1.0`). +3. If an instance has that label, use it. Do not rent again. +4. If none appears, re-search, then rent with a fresh offer id and a **new** `label`. +5. After any retry, keep checking for the original label. If it appears later, destroy whichever instance you do not want. + | Symptom | Typical response | What to do | | --- | --- | --- | | Target outside `[0, 1)` (negative, or 1 or above) | HTTP 400 `invalid_args` ("target reliability must be greater than or equal to 0 and less than 1") | SLA requires `0 < target_reliability < 1`. Sending `0` or omitting the field rents **without** an SLA (HTTP 200, no error). | @@ -321,7 +331,7 @@ curl -s -G "https://console.vast.ai/api/v0/charges/" \ | Offer no longer exists | HTTP 400 `invalid_args` (`msg` may contain `error 404/3603`), HTTP 404 `no_such_ask` (`msg` may contain `error 404/3659` if the offer was taken mid-request), or HTTP 410 | Re-search and use a fresh offer ID. Do not retry the same ID. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | -| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | There is no idempotency key. Put a unique `label` on the rent body. Look it up with URL-encoded `select_filters` (`curl -G --data-urlencode 'select_filters={"label":{"eq":"YOUR_LABEL"}}'`) a few times, about a second apart (Show Instances threshold `1.0`). If any lookup returns a row, do not PUT again. If none do, re-search and retry with a fresh offer id and a **new** `label`. After any retry, keep checking for the original label on your next few polls. If it appears later, destroy whichever instance you do not want. | +| Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | See [If the rent outcome is unknown](#if-the-rent-outcome-is-unknown). | | Too many requests | HTTP 429. Search returns JSON. `error` is `HTTPTooManyRequests` for a short limit, or `search_quota_exceeded` when the daily row quota is used up. Rent 429s are not that JSON shape (usually an HTML page). Both include `Retry-After`. | If `error` is `search_quota_exceeded`, stop until `Retry-After` (it can be hours). Otherwise honor `Retry-After`. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | | CLI or SDK retried a rent on its own | The CLI and SDK retry connection errors, timeouts, and HTTP 429, 502, 503, and 504. They do not read `Retry-After`. They cannot set `target_reliability`. | For an SLA rent you send yourself, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | | Daily search row quota | HTTP 429 with `error: "search_quota_exceeded"`. `Retry-After` points at the quota reset and can be hours away. Not every account is capped the same way. | Stop scanning. Honor `Retry-After`. Do not retry in a loop, and do not shard the same search to get around it. | diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 5618db90..b2cab5b4 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (**Reliability Commitment**, or **Confidence**, which is the fee margin) that would raise a contract's SLA fee is not applied to that contract. A contract skipped only for that fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (**Reliability Commitment**, or **Confidence**, which is the fee margin) that would raise a contract's SLA fee means that contract is **not extended** by that request. A contract's SLA terms are locked when it is rented and never change. A contract skipped only for that fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. @@ -251,12 +251,8 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **If you are sure SLA was never on during any current rental:** unlist so no new rentals start, then wait for those rentals to end before you take the machine offline. -- **If you are not sure:** do not unlist. Keep the machine listed and schedule a maintenance window (the SLA path below). - -Do not move the offer end date to prepare for maintenance. Any end date you send extends every active rental that ends before it. - -- **SLA rentals:** Stay listed and schedule maintenance as far ahead as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Unlist only if you are sure SLA was never on during a current rental. If you do unlist, write down every field on **Set Pricing** first (GPU price, minimum GPUs, end date, storage, bandwidth, reserved discount, min bid, **Reliability Commitment**, and **Confidence**) and re-enter all of them before **LIST**. A blank bandwidth price publishes at $0. See [Severe outage](/host/sla-offers#when-things-go-wrong). Do not move the end date later. That extends every shorter SLA contract and its credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +- **Planned work:** stay listed and [schedule a maintenance window](/host/sla-offers#scheduled-maintenance). +- **Outage, machine still online, and you need to stop new rentals:** you may unlist. First write down every **Set Pricing** field (GPU price, minimum GPUs, end date, storage, bandwidth, reserved discount, min bid, **Reliability Commitment**, and **Confidence**). Unlisting does not change existing rentals, but it drops the SLA ask. A blank bandwidth price publishes at $0 when you relist. Do not move the offer end date. Sending one extends every shorter rental. See [Severe outage](/host/sla-offers#when-things-go-wrong). Pick the path that matches your situation: diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 34ee9a70..96712fd6 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -303,6 +303,7 @@ extra="" [ -n "${END:-}" ] && extra="${extra}&end_date=${END}" [ -n "${T:-}" ] && extra="${extra}&r_target=${T}" machines=$(vastai show machines --raw --api-key "$VAST_API_KEY") +echo "note: machines offline more than about 10 hours are not in this list; compare the count with Host → Machines" >&2 for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ '.machines[] | select((.id|tostring) == $id)') diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index cde031b2..1c8efc61 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -330,7 +330,6 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ "price_inetu": CURRENT_INET_UP, "price_inetd": CURRENT_INET_DOWN, "credit_discount_max": CURRENT_DISCOUNT, - "price_min_bid": CURRENT_MIN_BID, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, @@ -358,7 +357,6 @@ SLA fields example (existing listing, no extension). Same fields as the curl abo "price_inetu": CURRENT_INET_UP, "price_inetd": CURRENT_INET_DOWN, "credit_discount_max": CURRENT_DISCOUNT, - "price_min_bid": CURRENT_MIN_BID, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, @@ -581,7 +579,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `show machines` returns `min_bid_price` (your host-side minimum bid, net of the platform fee, same idea as `listed_gpu_cost`). The value you read back can differ slightly from what you sent. Resend the `price_min_bid` you wrote down if you need to change it. On an existing ask, omitting it keeps the stored minimum. After an unlist, resend it: do not rely on the stored value. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. A storage price of `0` also keeps the stored price. Omitting `price_disk` is different: it resets storage to $0.10. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `listed_gpu_cost` round-trips: send it back as `price_gpu` and the price does not change. `min_bid_price` is different. It is reported net of the platform fee and does not round-trip, so never resend it as `price_min_bid`. On an existing ask, omitting `price_min_bid` keeps the stored minimum. After an unlist, send the value you wrote down. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. A storage price of `0` also keeps the stored price. Omitting `price_disk` is different: it resets storage to $0.10. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. @@ -739,7 +737,7 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **Or use CLI/REST below.** Forgiveness is not guaranteed either way. -**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Notice rules are in the note above. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. Include `duration` (whole hours) and `maintenance_category`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. +**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Notice rules are in the note above. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. **`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -905,11 +903,15 @@ curl -s -H "Authorization: Bearer $VAST_API_KEY" \ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA settlement in the window. Do **not** read `per_day[].sla_earn` for single-machine checks — `per_day[]` is always fleet-wide, even with `?machid=`. **Quick rules:** -- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Pull several hours after UTC midnight (for example 06:00 UTC). Later corrections can change `sla_earn`. A multi-day window returns one total per machine, so it shows that the window changed, not which day. For a per-machine daily record, call earnings once per UTC day (`sday=eday=D`, no `machid`) for each of the last 7 days, at least 2 seconds apart, and compare `per_machine[].sla_earn` with the value you stored for that machine and day. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover—not as a strict match to one settled UTC calendar day. +- **One machine, one UTC day:** Use `sday`/`eday` with `day = floor(unix_epoch_seconds / 86400)`, or CLI `--start_date` / `--end_date` with an explicit UTC time (`YYYY-MM-DDT00:00:00Z`; bare dates are parsed in local time). Example: `2026-07-24` 00:00 UTC is unix `1784851200` → `sday=eday=20658`. Pull several hours after UTC midnight (for example 06:00 UTC). Later corrections can change `sla_earn`. A multi-day window is one total per machine, not a daily series. For a daily record, see [Daily per-machine record](#daily-per-machine-record). - **Fleet, exact UTC day (one call):** omit `machid` and set `sday` and `eday` to the same day index. Read `per_machine[].sla_earn`. - **Recent window (`last_days`, coarse):** one request without `machid` returns all machines in `per_machine[]`. `last_days=1` spans yesterday and today-so-far. +#### Daily per-machine record + +Call earnings once per UTC day (`sday=eday=D`, no `machid`) for each of the last 7 days, at least 2 seconds apart, and compare `per_machine[].sla_earn` with the value you stored for that machine and day. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover, not as a match to one settled UTC calendar day. + ```bash # Exact UTC day 2026-07-24 for machine 12345 (sday/eday = 20658) curl -s -H "Authorization: Bearer $VAST_API_KEY" \ From 4da6f81a30e377f38bd5c2faad79a03502725dab Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 03:58:05 -0700 Subject: [PATCH 216/250] docs(sla): address doc-review consensus (cycle 161) Fleet scripts now treat a CLI HTTP error as a failed command, because the CLI exits 0. Co-authored-by: Cursor --- cli/rate-limits.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- guides/reference/billing.mdx | 1 + host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 5 +++- host/sla-offers.mdx | 32 ++++++++++++---------- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 47036e48..12ef4e91 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -9,7 +9,7 @@ This page covers the error format, how rate limits work, and how to configure th ## Error Responses -When a CLI command fails, it prints the error message from the API and exits with a non-zero status code. The underlying API error shape is: +When the server returns an HTTP error, the CLI prints it to stderr and exits with status 0. With `--raw`, that stderr line is JSON: `{"error": true, "status_code": N, "msg": "…"}`. Scripts must check the output, not the exit status. The underlying API error shape is: ```json { diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 2d4cb25f..41532256 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -372,7 +372,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **Stop vs destroy.** - **Stop:** How **Stop** and **Loading** time are billed on an SLA rental is not guaranteed. Budget as if both can still be charged. Only **Destroy** reliably ends GPU and SLA charges, and Destroy deletes the disk. Check **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy**. -- **Zero balance:** At $0.00 a stopped SLA instance can keep the balance negative while its data is scheduled for deletion if you have no saved card. See [Negative Balances](/guides/reference/billing#negative-balances). +- **Zero balance:** At a $0.00 balance, a stopped SLA instance can keep accruing charges. If you have no saved card, the instance and its data are scheduled for deletion. If you have a saved card, auto-stop is not a reliable way to end those charges. Destroy the instance if you do not plan to resume. See [Negative Balances](/guides/reference/billing#negative-balances). - **Downtime you cause:** Contact support before you count on a service credit for your own Stop or reboot, a bad image, a container crash, or a stop at zero balance. - **Final settlement:** The net SLA row still posts when the contract closes. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index cea4ef9d..f6e63b31 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -29,6 +29,7 @@ Once your credits reach \$0.00, your instances, storage volumes, and data **will - **If you have a credit card saved:** - Your credit card will be periodically and automatically charged to cover any negative balance. - This protects your instances from being deleted and allows you to resume them without losing data. + - On an SLA rental, a saved card does not by itself end GPU and SLA charges after an automatic stop. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - **If you do not have a credit card saved:** - The system will have no backup payment method to charge, and will not be able to top up your balance. - Your instances and stored data will be **destroyed** to prevent indefinite unpaid usage. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index b2cab5b4..b55ed996 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -252,7 +252,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. - **Planned work:** stay listed and [schedule a maintenance window](/host/sla-offers#scheduled-maintenance). -- **Outage, machine still online, and you need to stop new rentals:** you may unlist. First write down every **Set Pricing** field (GPU price, minimum GPUs, end date, storage, bandwidth, reserved discount, min bid, **Reliability Commitment**, and **Confidence**). Unlisting does not change existing rentals, but it drops the SLA ask. A blank bandwidth price publishes at $0 when you relist. Do not move the offer end date. Sending one extends every shorter rental. See [Severe outage](/host/sla-offers#when-things-go-wrong). +- **Outage, machine still online, and you need to stop new rentals:** you may unlist. Before you unlist, record every **Set Pricing** field: GPU, storage, and bandwidth prices; minimum GPUs; reserved discount (omitted on a new ask becomes `0.4`); min bid; offer end date and auto-renew duration; whether the listing is **hidden**; and **Reliability Commitment** and **Confidence**. Unlisting does not change existing rentals, but it drops the SLA ask. A blank bandwidth price publishes at $0 when you relist. When you relist, read [Severe outage step 6](/host/sla-offers#severe-outage) before choosing an end date: check the latest rental end date on **Host → Machines**, then wait until it passes or accept that shorter rentals will be extended. Pick the path that matches your situation: diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 96712fd6..365126a5 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -302,7 +302,10 @@ extra="" [ -n "${START:-}" ] && extra="${extra}&start_date=${START}" [ -n "${END:-}" ] && extra="${extra}&end_date=${END}" [ -n "${T:-}" ] && extra="${extra}&r_target=${T}" -machines=$(vastai show machines --raw --api-key "$VAST_API_KEY") +# The CLI prints HTTP errors to stderr and exits 0. Check stdout, not $?. +machines=$(vastai show machines --raw --api-key "$VAST_API_KEY" 2>"$BT_DIR/cli.err") +printf '%s' "$machines" | jq -e '.machines | type == "array"' >/dev/null \ + || { echo "show machines failed (check machine_read); see $BT_DIR/cli.err" >&2; exit 1; } echo "note: machines offline more than about 10 hours are not in this list; compare the count with Host → Machines" >&2 for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1c8efc61..a2e28947 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -25,7 +25,7 @@ SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. -Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong). Skip [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) and API automation unless you manage many machines with scripts. +Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong). Skip [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) and API automation unless you manage many machines with scripts. The console shows fleet-wide totals, with SLA folded into earnings. Per-machine SLA amounts need the CLI and an API key with `billing_read`. | Goal | Start here | @@ -242,7 +242,7 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover ## Listing an SLA offer -**Console hosts:** use [Web console](#web-console) and, after you list, [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). [API (for automation)](#api-for-automation) and [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) are for API keys. +**Console hosts:** use [Web console](#web-console) and, after you list, [Console (fleet totals only)](#console-fleet-totals-only). [API (for automation)](#api-for-automation) and [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) are for API keys. ### Web console @@ -403,7 +403,7 @@ Use this loop only to restore SLA offers that no longer appear in search on mach -**Console hosts:** skip this section. Enable an SLA with [Web console](#web-console) and check settlement in [Console (recommended for day-to-day checks)](#console-recommended-for-day-to-day-checks). +**Console hosts:** skip this section. Enable an SLA with [Web console](#web-console) and check settlement in [Console (fleet totals only)](#console-fleet-totals-only). @@ -446,6 +446,7 @@ This example is illustrative: it sleeps between machines and logs success/error ```bash : "${VAST_API_KEY:?export VAST_API_KEY first (needs machine_write and machine_read)}" : "${SEARCH_API_KEY:?export SEARCH_API_KEY first (needs misc, on its own key)}" +BTERR=$(mktemp) # Do not reuse this loop to change SLA terms on machines that have rentals. # It resends end_date or duration, which extends every shorter active contract. # Leave DRY_RUN=1 until you confirm each machine is **Listed** (or on your allowlist). @@ -471,15 +472,21 @@ DRY_RUN="${DRY_RUN:-1}" if [ "$DRY_RUN" = "0" ] && [ -z "$ALLOWLIST" ]; then echo "abort: set ALLOWLIST to Listed machine IDs before DRY_RUN=0" >&2; exit 1 fi -# If no SLA offers exist marketplace-wide, SLA may be off. Do not re-list the fleet. -canary=$(vastai search offers 'has_sla=true verified=any' --limit 1 --raw --retry 1 --api-key "$SEARCH_API_KEY") \ - || { echo "Canary search failed; aborting." >&2; exit 1; } -if ! printf '%s' "$canary" | jq -e 'type == "array" and length > 0' >/dev/null; then +# The CLI prints HTTP errors to stderr and exits 0. Check stdout, not $?. +# "Warning: Unrecognized field" for has_sla goes to stderr and does not affect jq. +canary=$(vastai search offers 'has_sla=true verified=any' --limit 1 --raw --retry 1 --api-key "$SEARCH_API_KEY" 2>"$BTERR") +if ! printf '%s' "$canary" | jq -e 'type == "array"' >/dev/null; then + echo "Canary search failed; see $BTERR" >&2 + exit 1 +fi +if [ "$(printf '%s' "$canary" | jq 'length')" -eq 0 ]; then echo "No SLA offers marketplace-wide (SLA may be disabled). Aborting." >&2 exit 1 fi sleep 6 -machines=$(vastai show machines --raw --api-key "$VAST_API_KEY") +machines=$(vastai show machines --raw --api-key "$VAST_API_KEY" 2>"$BTERR") +printf '%s' "$machines" | jq -e '.machines | type == "array"' >/dev/null \ + || { echo "show machines failed (check machine_read); see $BTERR" >&2; exit 1; } for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ -n "$ALLOWLIST" ] && ! echo "$ALLOWLIST" | grep -qw "$id"; then echo "skip $id: not in ALLOWLIST"; continue @@ -524,12 +531,9 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do fi # A failed search must not become a PUT. Fully rented machines are also absent from search. sleep 6 - if ! out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --retry 1 --api-key "$SEARCH_API_KEY" 2>/dev/null); then - echo "skip $id: search failed (missing misc permission or HTTP 429)" >&2 - continue - fi + out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --retry 1 --api-key "$SEARCH_API_KEY" 2>"$BTERR") if ! printf '%s' "$out" | jq -e 'type == "array"' >/dev/null; then - echo "skip $id: search returned non-array output" >&2 + echo "skip $id: search failed (missing misc permission or HTTP 429); see $BTERR" >&2 continue fi if printf '%s' "$out" | jq -e 'length > 0' >/dev/null; then @@ -833,7 +837,7 @@ After you enable SLA, charges and credits settle on UTC (Coordinated Universal T - SLA-contract compute is not included in `gpu_earn`, `sto_earn`, or bandwidth earnings. `sla_earn` is negative only when a prior day is corrected. - `per_day[].sla_earn` is fleet-wide even when you pass a machine ID. Use `per_machine[].sla_earn` for one machine. -### Console (recommended for day-to-day checks) +### Console (fleet totals only) 1. Go to **Host → Billing**. 2. Set the date range to include the UTC day you want to review. From 9d409d8dcec50ef27ae9d453135eed3a9d662276 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 04:06:59 -0700 Subject: [PATCH 217/250] docs(sla): address doc-review consensus (cycle 162) Print the backtester CLI error before the temp dir is removed, and stop treating search storage as the rent disk size. Co-authored-by: Cursor --- api-reference/openapi.yaml | 11 ++++---- api-reference/openapi/yaml/search_offers.yaml | 4 +-- host/sla-backtester.mdx | 8 ++++-- sdk/python/reference/create-instance.mdx | 26 ++++++++++++++++++- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 3fafaa01..8adb9d97 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -6912,12 +6912,11 @@ paths: maxItems: 2 allocated_storage: type: number - description: 'Storage allocation size in GB for the instance. - - This sets the disk size when creating the instance and cannot - be changed later. - - Default is 8GB. + description: 'Storage size in GB used to price offers in this search + only. It is not carried into rent. Send the same value as `disk` + on `PUT /api/v0/asks/{id}/`. If `disk` is omitted or 0 at rent, + 10 GB is allocated. Values below 8 are raised to 8. Disk size + cannot be changed after the instance is created. ' example: diff --git a/api-reference/openapi/yaml/search_offers.yaml b/api-reference/openapi/yaml/search_offers.yaml index 5f3e3b84..b0dfba43 100644 --- a/api-reference/openapi/yaml/search_offers.yaml +++ b/api-reference/openapi/yaml/search_offers.yaml @@ -276,9 +276,7 @@ paths: allocated_storage: type: number description: | - Storage allocation size in GB for the instance. - This sets the disk size when creating the instance and cannot be changed later. - Default is 8GB. + Storage size in GB used to price offers in this search only. It is not carried into rent. Send the same value as `disk` on `PUT /api/v0/asks/{id}/`. If `disk` is omitted or 0 at rent, 10 GB is allocated. Values below 8 are raised to 8. Disk size cannot be changed after the instance is created. example: limit: 100 type: ondemand diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 365126a5..802ae0e7 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -304,8 +304,12 @@ extra="" [ -n "${T:-}" ] && extra="${extra}&r_target=${T}" # The CLI prints HTTP errors to stderr and exits 0. Check stdout, not $?. machines=$(vastai show machines --raw --api-key "$VAST_API_KEY" 2>"$BT_DIR/cli.err") -printf '%s' "$machines" | jq -e '.machines | type == "array"' >/dev/null \ - || { echo "show machines failed (check machine_read); see $BT_DIR/cli.err" >&2; exit 1; } +printf '%s' "$machines" | jq -e '.machines | type == "array"' >/dev/null +if [ $? -ne 0 ]; then + echo "show machines failed (check machine_read):" >&2 + cat "$BT_DIR/cli.err" >&2 + exit 1 +fi echo "note: machines offline more than about 10 hours are not in this list; compare the count with Host → Machines" >&2 for id in $(echo "$machines" | jq -r '.machines[].id'); do machine=$(echo "$machines" | jq -c --arg id "$id" \ diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index b765f4ea..9284be5f 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -259,8 +259,32 @@ except requests.HTTPError as exc: ) response.raise_for_status() contract_id = response.json().get("new_contract") - except (requests.Timeout, requests.ConnectionError, requests.HTTPError): + except (requests.Timeout, requests.ConnectionError): contract_id = None + except requests.HTTPError as retry_exc: + retry_resp = retry_exc.response + retry_status = retry_resp.status_code if retry_resp is not None else 0 + try: + retry_body = retry_resp.json() if retry_resp is not None else {} + except ValueError: + retry_body = {} + retry_err = retry_body.get("error", "") if isinstance(retry_body, dict) else "" + retry_msg = retry_body.get("msg", "") if isinstance(retry_body, dict) else "" + offer_gone = ( + retry_status in (404, 410) + or retry_err in ("no_such_ask", "invalid_price") + or (retry_err == "invalid_args" and "404/3603" in str(retry_msg)) + ) + if retry_status == 429 or retry_status >= 500: + contract_id = None + elif offer_gone: + raise RuntimeError( + "Offer is gone or its price changed. Re-search and retry with a new offer id and a new label. Do not retry this offer id." + ) from retry_exc + else: + raise RuntimeError( + f"Rent failed ({retry_status} {retry_err}): {retry_msg}. Fix the request or account. Do not retry this offer id." + ) from retry_exc else: offer_gone = ( status in (404, 410) From e3337dcb487bf7424e0776466bcf27980022c4df Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 04:14:34 -0700 Subject: [PATCH 218/250] docs(sla): address doc-review consensus (cycle 163) Count every hour the contract existed when reconciling an SLA fee, and skip hidden machines in the re-list loop unless asked. Co-authored-by: Cursor --- api-reference/openapi.yaml | 9 +++++---- .../openapi/yaml/create_instance.yaml | 4 ++-- api-reference/rate-limits-and-errors.mdx | 2 +- cli/reference/create-instance.mdx | 4 ++-- guides/instances/choosing/sla-coverage.mdx | 6 +++--- host/hosting-overview.mdx | 6 +++++- host/sla-backtester.mdx | 8 ++++---- host/sla-offers.mdx | 19 +++++++++++++------ 8 files changed, 35 insertions(+), 23 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 8adb9d97..56f93b34 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1841,9 +1841,10 @@ paths: schema: $ref: '#/components/schemas/Error' '403': - description: 'Forbidden. SLA is not enabled for this account or region (`error` - is `sla_disabled`). A host account renting another host''s offer is not - 403; that is HTTP 400 with `error 403/3586` inside `msg`. + description: 'Forbidden. SLA is not enabled (`error` is `sla_disabled`). + This is a platform-wide switch, not an account or region setting. A host + account renting another host''s offer is not 403; that is HTTP 400 with + `error 403/3586` inside `msg`. ' content: @@ -1891,7 +1892,7 @@ paths: '429': description: Too Many Requests. Body follows the Accept header (usually HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers - are set. `penalty` is not applied on this route. + are set. content: text/html: schema: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 523adc8c..1a9833f2 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -229,7 +229,7 @@ paths: $ref: '#/components/schemas/Error' '403': description: | - Forbidden. SLA is not enabled for this account or region (`error` is `sla_disabled`). A host account renting another host's offer is not 403; that is HTTP 400 with `error 403/3586` inside `msg`. + Forbidden. SLA is not enabled (`error` is `sla_disabled`). This is a platform-wide switch, not an account or region setting. A host account renting another host's offer is not 403; that is HTTP 400 with `error 403/3586` inside `msg`. content: application/json: schema: @@ -269,7 +269,7 @@ paths: type: integer example: 1234567 '429': - description: Too Many Requests. Body follows the Accept header (usually HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers are set. `penalty` is not applied on this route. + description: Too Many Requests. Body follows the Accept header (usually HTML, not the JSON error shape). Retry-After and X-RateLimit-* headers are set. content: text/html: schema: diff --git a/api-reference/rate-limits-and-errors.mdx b/api-reference/rate-limits-and-errors.mdx index b481e3df..f1534c22 100644 --- a/api-reference/rate-limits-and-errors.mdx +++ b/api-reference/rate-limits-and-errors.mdx @@ -45,7 +45,7 @@ The combined API reference does not always show each operation's `x-rate-limit` When you hit a rate limit, you will receive **HTTP 429**. There are two families: -- **Legacy-limited routes** (rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, listing `PUT /api/v0/machines/create_asks/`, and machine earnings `GET /api/v0/users/{user_id}/machine-earnings/`): the body is not the JSON `{"error": …}` shape. With the default `Accept: */*` (curl, `requests`) it is usually an HTML page. With `Accept: application/json` it is a generic JSON error. Detect the limit by HTTP status 429 and `Retry-After`. The rent route does not apply a penalty on top of that threshold. +- **Legacy-limited routes** (rent `PUT /api/v0/asks/{id}/`, `GET /api/v1/instances/`, listing `PUT /api/v0/machines/create_asks/`, and machine earnings `GET /api/v0/users/{user_id}/machine-earnings/`): the body is not the JSON `{"error": …}` shape. With the default `Accept: */*` (curl, `requests`) it is usually an HTML page. With `Accept: application/json` it is a generic JSON error. Detect the limit by HTTP status 429 and `Retry-After`. - **JSON 429:** search `POST /api/v0/bundles/`, charges `GET /api/v0/charges/`, the other earnings routes, schedule maintenance, and the SLA backtester. The body is `{"error": "HTTPTooManyRequests", "msg": "API requests too frequent", "retry_after": …}`. A daily search quota hit uses the same shape with `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. Both kinds include a `Retry-After` header and `X-RateLimit-*` headers. Honor `Retry-After` when you see it. The CLI and SDK never read `Retry-After`. diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 2d2f6226..a7e0493d 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -155,8 +155,8 @@ vastai create instance 1000001 --template_hash TEMPLATE_HASH --disk 64 vastai create instance 1000002 --image pytorch/pytorch --disk 40 --env '-p 8081:8081/udp -h billybob' --ssh --direct --onstart-cmd "env | grep _ >> /etc/environment; echo 'starting up'"; # create an on-demand instance with a private image -# replace YOUR_USER / YOUR_PASSWORD with your registry credentials -vastai create instance 1000003 --image YOUR_REGISTRY/pytorch:latest --login '-u YOUR_USER -p YOUR_PASSWORD docker.io' --jupyter --direct --env '-e TZ=PDT -e XNAME=XX4 -p 22:22 -p 8080:8080' --disk 20 +# Put a registry access token in REGISTRY_TOKEN. Do not put your account password on the command line. +vastai create instance 1000003 --image YOUR_REGISTRY/pytorch:latest --login "-u YOUR_USER -p $REGISTRY_TOKEN docker.io" --jupyter --direct --env '-e TZ=PDT -e XNAME=XX4 -p 22:22 -p 8080:8080' --disk 20 # create an on-demand instance with the pytorch/pytorch image, 40GB of disk, override the entrypoint to bash and pass bash a simple command to keep the instance running. (args launch without ssh/jupyter) vastai create instance 1000004 --image pytorch/pytorch --disk 40 --onstart-cmd 'bash' --args -c 'echo hello; sleep infinity;' diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 41532256..40145238 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -298,7 +298,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta 1. Call Show Charges for one UTC day. `day.gte` and `day.lte` are both required (unix seconds). Set `day.lte` to `day.gte + 86399`. 2. Page with `after_token` / `next_token` until `next_token` is `null`. Space calls about one second apart. 3. Find the row whose `source` is `instance-` plus the contract id from `new_contract`, then the `items[]` entry with `type: "sla"`. -4. Compare that amount with the stored hourly fee times the hours the contract was active that day. A smaller or negative amount usually means a credit was applied. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. How the console labels the row is in [Settlement timing](#settlement-timing). +4. Compare that amount with the stored hourly fee times every hour the contract existed that UTC day, including downtime. The SLA fee keeps billing during outages, so do not count only running hours. A smaller or negative amount usually means a credit was applied. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. How the console labels the row is in [Settlement timing](#settlement-timing). The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. If `next_token` is not `null`, repeat the request with `after_token` set to that value before you treat a missing `sla` item as unsettled. `limit` defaults to 100, so a busy account can put the contract on a later page. @@ -327,7 +327,7 @@ A timeout, a dropped connection, or HTTP 5xx means the rental may already exist. | --- | --- | --- | | Target outside `[0, 1)` (negative, or 1 or above) | HTTP 400 `invalid_args` ("target reliability must be greater than or equal to 0 and less than 1") | SLA requires `0 < target_reliability < 1`. Sending `0` or omitting the field rents **without** an SLA (HTTP 200, no error). | | Offer has no SLA, target is above the host commitment, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | -| SLA not available | HTTP 403 `sla_disabled` | SLA is not enabled for this request. It may be off platform-wide or for this account. Do not retry in a loop. Rent without a reliability target, or contact support. | +| SLA not available | HTTP 403 `sla_disabled` | SLA is not enabled. This is a single platform-wide switch, not an account or region setting. Do not retry in a loop. Rent without a reliability target, or contact support. | | Offer no longer exists | HTTP 400 `invalid_args` (`msg` may contain `error 404/3603`), HTTP 404 `no_such_ask` (`msg` may contain `error 404/3659` if the offer was taken mid-request), or HTTP 410 | Re-search and use a fresh offer ID. Do not retry the same ID. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | @@ -489,7 +489,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. Compare it with the **SLA Fee/hr** you wrote down at rent (console quick start step 4) times the hours the contract was active that UTC day, including downtime. The Charges API returns the same net. Invoices do not. You cannot see the measured reliability for that day in the console or the API. +**Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. Compare it with the **SLA Fee/hr** you wrote down at rent (console quick start step 4) times every hour the contract existed that UTC day, including downtime. The Charges API returns the same net. Invoices do not. You cannot see the measured reliability for that day in the console or the API. **API integrators:** Use the same Charges row as [Settlement timing](#settlement-timing). The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. A row below the fee you expected means a credit was applied. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index b55ed996..e2ed4ad8 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -264,6 +264,10 @@ For SLA maintenance-forgiveness rules, notice windows, and confirmation steps, s ## Uninstalling + +Unlist first, then wait until the latest rental end date shown on **Host → Machines** has passed (see [Maintenance](#maintenance)). Uninstalling while rentals are active breaks those contracts and, on SLA rentals, can lead to service credits. + + To uninstall, use the Vast uninstall script located at https://s3.amazonaws.com/vast.ai/uninstall. ## Common Questions @@ -296,7 +300,7 @@ To apply for datacenter status we have a number of requirements. There is a mini ### How do I uninstall vast from my machine? -You can use the [uninstall script](https://s3.amazonaws.com/vast.ai/uninstall) +Unlist first and wait until active rentals have ended. Uninstalling during a rental breaks that contract. On an SLA rental it can lead to service credits. You can use the [uninstall script](https://s3.amazonaws.com/vast.ai/uninstall) ### What is this red error message on my machine? diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 802ae0e7..517a0fde 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -26,7 +26,7 @@ How much could SLA settlement cost given your reliability commitment and confide ## When to use it -Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. History is usable from about mid-2026, when per-day rental active time started being recorded. Earlier days look idle. If `has_data` is `false`, move the window toward the present or pick a machine with more recent rental activity. Widening the window further into the past does not help. +Use the backtester before you enable SLA on a listing, or when you want to tune parameters. The machine needs at least a few weeks of rental history. Older windows may have no recorded SLA history. If `has_data` is `false`, move the window toward the present or pick a machine with more recent rental activity. Widening the window further into the past does not help. Use the backtester to: @@ -145,7 +145,7 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ **If you only read three things:** check `has_data` (if `false`, move the window toward the present or wait for more rental history), compare `r_eff` with `r_be`, then look at your [net SLA result and largest single-day credit](#summarize-with-jq). -A successful response looks like this (one `days` row shown; values are illustrative): +A successful response looks like this (one `days` row shown). These numbers are the response to the `r_target=0.95` request above, not the baseline request that omits `r_target`. ```json { @@ -179,7 +179,7 @@ A successful response looks like this (one `days` row shown; values are illustra | Field | Meaning | | --- | --- | -| `has_data` | `true` if the range had at least one day of rental activity to replay. `false` means no usable history in the window. Move the window toward the present (days before about mid-2026 look idle) or wait for more rental history. When `false`, every `days` row is zero with `reliability: null`, and `r_eff` is `null`. | +| `has_data` | `true` if the range had at least one day of rental activity to replay. `false` means no usable history in the window. Move the window toward the present, or wait for more rental history. Older windows may have no recorded SLA history. When `false`, every `days` row is zero with `reliability: null`, and `r_eff` is `null`. | | `start_day`, `end_day` | UTC day indices, `day = floor(epoch_seconds / 86400)`. `day × 86400` is exactly 00:00 UTC on that date. Convert with `date -u -d "@$((day * 86400))" +%F` (Linux) or `date -u -r $((day * 86400)) +%F` (macOS). Show Earnings `sday` / `eday` use the same day index. | | `r_eff` | **Effective reliability**: the constant reliability that would have produced the service credits paid in this window. `null` when nothing was paid into escrow in the window (all `client_*_to_escrow` values are zero, as with `has_data: false`). | | `r_be` | **Break-even reliability**: the reliability at which SLA fees and service credits cancel out. Always present. | @@ -359,7 +359,7 @@ Expect about three seconds per machine (`sleep 3` plus request time), so budget ## When stuck -- **`has_data: false`** — Move the window toward the present, or wait for rental history. Widening it further into the past does not help. Days before about mid-2026 look idle. +- **`has_data: false`** — Move the window toward the present, or wait for rental history. Widening it further into the past does not help. Older windows may have no recorded SLA history. - **`400 bad_request` on a request that used to work** — Replace `r=` with `r_claim=` and remove `reliability=`. - **`401` / `403 auth_error` / `404 auth_error`** — Check that the `Authorization: Bearer` header is present, the key is complete (64 characters), and it has `machine_read`. - **Still stuck** — Ask in the [host Discord](https://discord.gg/hSuEbSQ4X8). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index a2e28947..ad32ad55 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -44,7 +44,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Reliability Commitment** and **Confidence**. In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. With no history, start the commitment below the uptime you expect to deliver, and start **Confidence** at **Low** (wide margin). Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. +7. Enter **Reliability Commitment** and **Confidence**. Prefer a few weeks of rentals, then a [backtester](/host/sla-backtester) run, before you enable SLA. If you enable it earlier, the commitment is a guess: start it below the uptime you expect, and start **Confidence** at **Low** (wide margin). In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Confirm an **SLA Fee** line. If that line is missing on every offer, SLA may be off platform-wide. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. @@ -126,7 +126,7 @@ When a client rents an on-demand instance on your SLA-listed offer with a chosen - **Strong reliability relative to the client's target** → you keep the SLA fee for that day. - **Shortfalls** → credits flow to the client from your earnings (bounded by that day's covered compute). -Over many strong days, SLA fees can offset occasional credits, but a single bad day can exceed months of collected charges — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. +Over many strong days, SLA fees can offset occasional credits, but a single bad day can exceed months of collected SLA fees — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. ### How reliability is measured @@ -399,7 +399,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge Use this loop only to restore SLA offers that no longer appear in search on machines with **zero** rentals. It does not change prices or SLA terms. To change terms, use [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). `current_rentals_resident`, `credit_discount_max`, and `min_bid_price` are on `GET /api/v0/machines/` but are not all in the Show Machines OpenAPI schema yet. A typed client that drops `current_rentals_resident` will skip every machine. -"Missing from search" also matches every **hidden** listing (hidden listings are not shown in search) and every **offline** machine (`create_asks` returns HTTP 402 until the machine is online). Any hidden machine not listed in `HIDDEN_IDS` becomes **public** on a live run. Machines in `HIDDEN_IDS` show up as "would re-list" in every dry run. That is expected. Set `HIDDEN_IDS` before `DRY_RUN=0` (space-separated IDs, or `HIDDEN_IDS=none` if you have no hidden listings). +"Missing from search" also matches every **hidden** listing (hidden listings are not shown in search) and every **offline** machine (`create_asks` returns HTTP 402 until the machine is online). Any hidden machine not listed in `HIDDEN_IDS` becomes **public** on a live run. The loop skips machines in `HIDDEN_IDS` unless you set `RELIST_HIDDEN=1`. Set `HIDDEN_IDS` before `DRY_RUN=0` (space-separated IDs, or `HIDDEN_IDS=none` if you have no hidden listings). @@ -514,7 +514,13 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do fi fi hidden=false - if echo "$HIDDEN_IDS" | grep -qw "$id"; then hidden=true; fi + if echo "$HIDDEN_IDS" | grep -qw "$id"; then + if [ "${RELIST_HIDDEN:-0}" != 1 ]; then + echo "skip $id: hidden listing; search cannot confirm it is missing (set RELIST_HIDDEN=1 to force)" + continue + fi + hidden=true + fi # Opt-in only: skip machines with no positive reliability commitment (do not invent 0.99) if ! echo "$machine" | jq -e '(.sla_reliability_claim // 0) > 0' >/dev/null; then echo "skip $id: no SLA terms visible (SLA off, daemon below SLA minimum, or account not SLA-approved)"; continue @@ -763,7 +769,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ -d '{"sdate": START_UNIX_UTC, "duration": 2, "maintenance_category": "software"}' ``` -`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. See [Schedule Maintenance](/api-reference/machines/schedule-maint). +`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. There is no public REST endpoint for reading maintenance windows. Even if you schedule or cancel over REST, confirm the result with `vastai show maints --ids 'MACHINE_ID' --raw` or on the console **Maintenance** tab. Each machine should have exactly one window. See [Schedule Maintenance](/api-reference/machines/schedule-maint). **Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. In scripts, pass `--retry 1` on `schedule maint` and `cancel maint`. A retried PUT can create a second window if the first one was stored and the response was lost. Confirm exactly one window before you schedule the next machine. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). @@ -917,7 +923,8 @@ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA sett Call earnings once per UTC day (`sday=eday=D`, no `machid`) for each of the last 7 days, at least 2 seconds apart, and compare `per_machine[].sla_earn` with the value you stored for that machine and day. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover, not as a match to one settled UTC calendar day. ```bash -# Exact UTC day 2026-07-24 for machine 12345 (sday/eday = 20658) +# Spot check: one machine, one UTC day (2026-07-24, sday/eday = 20658). +# A daily record for the fleet omits machid. See the loop above this example's prose. curl -s -H "Authorization: Bearer $VAST_API_KEY" \ "https://console.vast.ai/api/v0/users/me/machine-earnings/?machid=12345&sday=20658&eday=20658" \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' From c46e3c1cfde0cdef39ee02fb3a7fce8aee23df46 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 04:21:29 -0700 Subject: [PATCH 219/250] docs(sla): address doc-review consensus (cycle 164) Add the missing severe-outage anchor and a fleet earnings loop, and use the console Confidence labels. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-backtester.mdx | 8 ++++---- host/sla-offers.mdx | 23 ++++++++++++++++------ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 40145238..09ecf9e3 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -103,7 +103,7 @@ Bandwidth is billed separately, based on usage (`inet_*` rates), and is **not** ### Example: H100 at $3.50/hr GPU -Searching with a **reliability target of 95%** on an offer where the host's **reliability commitment is 99%** with **Medium** confidence: +Searching with a **reliability target of 95%** on an offer where the host's **reliability commitment is 99%**: | Cost component | Approx. rate | | --- | --- | @@ -352,7 +352,7 @@ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** be When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and host confidence (how the host priced SLA around their reliability commitment) are fixed for that rental. When comparing offers, use the SLA fee line or `dph_total`. Host confidence is not shown in the web console and is not a setting you control. +1. **Contract terms lock in** — your reliability target and the host's reliability commitment are fixed for that rental. The host's pricing margin is also fixed, and it is not shown to you. When comparing offers, use the SLA fee line or `dph_total`. 2. **Charges and settlement** — compute, storage, and the SLA fee accrue while the rental contract is active, **including while the machine is offline**. That is different from a non-SLA rental. The net SLA row (SLA fee minus any service credit) settles once per UTC day. See [Settlement timing](#settlement-timing) and [What you pay during an outage](#what-you-pay-during-an-outage). 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA fee with no credit. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 517a0fde..124514da 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -86,7 +86,7 @@ Requires Bearer authentication. Rate-limited to about one request every two seco | --- | --- | --- | | `machine_id` | Yes | ID of your machine | | `r_claim` | Yes | Reliability commitment to simulate (the `sla_r_claim` you plan to list), greater than 0 and at most `0.99999`. Example: `0.99` = 99%. | -| `p` | No | Host confidence, greater than 0 and less than 1. Uses a different scale from listing `sla_sigma_x` — see [Confidence values](#confidence-values-p). Default: `0.6667` (Normal). | +| `p` | No | Host confidence, greater than 0 and less than 1. Uses a different scale from listing `sla_sigma_x` — see [Confidence values](#confidence-values-p). Default: `0.6667` (console **Medium**; Normal band). | | `r_target` | No | Renter reliability target to simulate. Must be greater than 0 and at most `r_claim`. Default: `r_claim`. | | `start_date` | No | Range start as Unix epoch seconds. Default: 90 days before `end_date`. | | `end_date` | No | Range end as Unix epoch seconds. Default: now. | @@ -248,7 +248,7 @@ The two values are exactly related: `p = 1 / (1 + sla_sigma_x)`, and `sla_sigma_ | Confidence `p` | Console | Band | Listing equivalent | | --- | --- | --- | --- | -| `0.83` | High | Tight | `sla_sigma_x ≈ 0.2` | +| `0.8333` | High | Tight | `sla_sigma_x ≈ 0.2` | | `0.6667` | Medium (default) | Normal | `sla_sigma_x ≈ 0.5` | | `0.50` | Low | Wide | `sla_sigma_x ≈ 1.0` | @@ -289,7 +289,7 @@ Optional, for API automation only. To check one machine, use the single-machine - The loop reads each machine's `sla_reliability_claim` and `sla_confidence` label from `show machines`. - For machines whose terms are not visible, set `R` (commitment) and `P` (confidence `p`) as fallbacks. That covers machines without SLA yet, and machines whose terms are hidden because they are unlisted, have an outdated daemon, or lack SLA approval. The loop logs every fallback it uses, so check those rows before trusting them. - Machines missing either value, with no `R`/`P` fallback, are skipped and logged. - - The confidence label is a band. The loop uses one `p` per band: `high` → 0.83 (σ 0.2), `medium` → 0.6667 (σ 0.5), `low` → 0.50 (σ 1.0). `low` covers every σ above 0.71, so a machine listed at σ 2.0 is backtested at `p` 0.50, not at its real `p`. For an exact value, use the single-machine request with `p = 1/(1 + sla_sigma_x)`. + - The confidence label is a band. The loop uses one `p` per band: `high` → 0.8333 (console **High**, σ 0.2), `medium` → 0.6667 (console **Medium**, σ 0.5), `low` → 0.50 (console **Low**, σ 1.0). `low` covers every σ above 0.71, so a machine listed at σ 2.0 is backtested at `p` 0.50, not at its real `p`. For an exact value, use the single-machine request with `p = 1/(1 + sla_sigma_x)`. 2. Responses are written to a private temp directory that is deleted when the loop exits. ```bash @@ -327,7 +327,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do label=$(echo "$machine" | jq -r '.sla_confidence // empty') [ "$used_r_fallback" = 1 ] && label="" case "$label" in - high) p=0.83 ;; + high) p=0.8333 ;; medium) p=0.6667 ;; low) p=0.50 ;; *) p="${P:-}" diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index ad32ad55..0d547e06 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -152,7 +152,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | | Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.99999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | -| Confidence spread | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | Pricing margin built into the SLA fee. Tight is a smaller fee. Wide is a larger fee. It does not change the credit you owe. Defaults to `0.5` only on a **new** ask. When you first enable SLA on an existing listing, send `sla_sigma_x` yourself. Omitting it leaves the stored value empty, so `show machines` reports no confidence. On an ask that already has a stored value, omitting `sla_sigma_x` keeps that value. | +| Confidence | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | Pricing margin built into the SLA fee. **High** is a smaller fee. **Low** is a larger fee. It does not change the credit you owe. Defaults to `0.5` (console **Medium**) only on a **new** ask. When you first enable SLA on an existing listing, send `sla_sigma_x` yourself. Omitting it leaves the stored value empty, so `show machines` reports no confidence. On an ask that already has a stored value, omitting `sla_sigma_x` keeps that value. | ### Advanced: `sla_max_beta` (optional) @@ -187,11 +187,11 @@ Do not assume the dashboard score equals SLA reliability. Before choosing `sla_r ### Confidence values -In the console, pick **High**, **Medium**, or **Low**. High is a tight margin (smaller SLA fee). Low is a wide margin (larger SLA fee), not a weak setting. You do not need the table unless you use the API or the backtester. +In the console, pick **High**, **Medium**, or **Low**. High is a tight margin (smaller SLA fee). Low is a wide margin (larger SLA fee), not a weak setting. The API, `show machines`, and the backtester use other names for the same setting. Use the console label. The table maps it to those other names. | Console | Band | API `sla_sigma_x` (σ) | Backtester `p` | `show machines` | Pricing effect | | --- | --- | --- | --- | --- | --- | -| High | Tight | `0.2` (band σ ≤ 0.32) | ~0.83 | `high` | Lowest client SLA fees at a given target | +| High | Tight | `0.2` (band σ ≤ 0.32) | ~0.8333 | `high` | Lowest client SLA fees at a given target | | Medium | Normal (default) | `0.5` (band σ ≤ 0.71) | ~0.6667 | `medium` | Balanced | | Low | Wide | `1.0` (band σ above 0.71) | ~0.50 | `low` | Highest client SLA fees at a given target | @@ -769,7 +769,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ -d '{"sdate": START_UNIX_UTC, "duration": 2, "maintenance_category": "software"}' ``` -`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. There is no public REST endpoint for reading maintenance windows. Even if you schedule or cancel over REST, confirm the result with `vastai show maints --ids 'MACHINE_ID' --raw` or on the console **Maintenance** tab. Each machine should have exactly one window. See [Schedule Maintenance](/api-reference/machines/schedule-maint). +`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. There is no public REST endpoint for reading maintenance windows. Even if you schedule or cancel over REST, confirm the result with `vastai show maints --ids 'MACHINE_ID' --raw` or on the console **Maintenance** tab. Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. Retries must not create a duplicate of the same one. See [Schedule Maintenance](/api-reference/machines/schedule-maint). **Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. In scripts, pass `--retry 1` on `schedule maint` and `cancel maint`. A retried PUT can create a second window if the first one was stored and the response was lost. Confirm exactly one window before you schedule the next machine. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). @@ -796,6 +796,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep - **`sla_disabled`** — SLA is off platform-wide. Do not retry in a loop. See [Getting help with SLA](#getting-help-with-sla). - **`sla_daemon_outdated`** — Update the host daemon from the [host setup guide](https://cloud.vast.ai/host/setup/), confirm the machine reconnects on **Host → Machines**, then retry LIST / `create_asks`. If the error persists, contact support with the machine ID. - **Unexpected credit** — `sla_earn` is not a per-contract credit record, and the backtester is an estimate, not the settlement. Contact support with the machine ID and the UTC dates. + - **Severe outage (active SLA contracts):** **Console** @@ -922,9 +923,19 @@ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA sett Call earnings once per UTC day (`sday=eday=D`, no `machid`) for each of the last 7 days, at least 2 seconds apart, and compare `per_machine[].sla_earn` with the value you stored for that machine and day. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover, not as a match to one settled UTC calendar day. +```bash +# Fleet daily record: omit machid. Illustrative only — add HTTP 429 backoff at fleet scale. +today=$(( $(date -u +%s) / 86400 )) +for d in $(seq $((today-7)) $((today-1))); do + curl -s -H "Authorization: Bearer $VAST_API_KEY" \ + "https://console.vast.ai/api/v0/users/me/machine-earnings/?sday=$d&eday=$d" \ + | jq -c --arg d "$d" '.per_machine[] | {day: ($d|tonumber), machine_id, sla_earn}' + sleep 2 +done +``` + ```bash # Spot check: one machine, one UTC day (2026-07-24, sday/eday = 20658). -# A daily record for the fleet omits machid. See the loop above this example's prose. curl -s -H "Authorization: Bearer $VAST_API_KEY" \ "https://console.vast.ai/api/v0/users/me/machine-earnings/?machid=12345&sday=20658&eday=20658" \ | jq '.per_machine[] | select(.machine_id == 12345 or .machine_id == "12345") | {machine_id, sla_earn}' @@ -952,7 +963,7 @@ Do **not** compare `last_days=7` totals to the backtester's largest single-day c ## Tips for competitive SLA offers - **Commit to a level you can sustain.** Clients who choose reliability targets below your reliability commitment see a lower SLA fee and still get a meaningful SLA. -- **Tighten confidence only when earned.** Use a tighter spread (`sla_sigma_x ≈ 0.2`) after you have a strong reliability track record on that machine. +- **Move to High only when earned.** Use **High** (`sla_sigma_x ≈ 0.2`) after you have a strong reliability track record on that machine. - **Keep the machine online during active contracts.** SLA credits and verification are separate systems, but both respond to downtime. - **SLA applies to on-demand rentals only.** It does not apply to interruptible/bid instances or reserved/prepay rentals. When a client starts an on-demand rental on an SLA-enabled offer, SLA terms lock for that rental contract and do not change if you later edit the offer. - **Use the [SLA backtester](/host/sla-backtester) (API-only)** to preview how different reliability commitments and confidence levels would have affected past earnings. From 1d416a313d6427f75c0705c6f38e6788ee38b0a3 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 04:29:28 -0700 Subject: [PATCH 220/250] docs(sla): address doc-review consensus (cycle 165) Point console hosts at Low confidence for a wider fee cushion, and say a daily credit is not a hard cap. Co-authored-by: Cursor --- api-reference/openapi.yaml | 5 ++++- api-reference/openapi/yaml/list_machine.yaml | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 12 ++++++------ 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 56f93b34..3561cbaa 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4673,7 +4673,10 @@ paths: type: array items: type: integer - description: IDs of newly created contracts + description: IDs of asks (offers) created by this request. + A non-empty list means a new ask was created, so new-ask + defaults such as sla_sigma_x 0.5 were applied. These are + not rental contract IDs. upd_contracts: type: array items: diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index beb771a5..650042f4 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -143,7 +143,7 @@ paths: type: array items: type: integer - description: IDs of newly created contracts + description: IDs of asks (offers) created by this request. A non-empty list means a new ask was created, so new-ask defaults such as sla_sigma_x 0.5 were applied. These are not rental contract IDs. upd_contracts: type: array items: diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 09ecf9e3..25964995 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -103,7 +103,7 @@ Bandwidth is billed separately, based on usage (`inet_*` rates), and is **not** ### Example: H100 at $3.50/hr GPU -Searching with a **reliability target of 95%** on an offer where the host's **reliability commitment is 99%**: +This example uses a **reliability target of 95%** on an offer whose host **reliability commitment is 99%**, with a 10 GB disk. The fee uses an illustrative host margin that is not shown on the offer. | Cost component | Approx. rate | | --- | --- | diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 124514da..09f7a0c4 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -232,7 +232,7 @@ Break-even territory: fees and credits roughly balance. A few bad days would tip ### `r_eff` below `r_be` -Under these terms, SLA would have cost you money over this window. Improve reliability, lower your reliability commitment, or choose wider confidence before listing. +Under these terms, SLA would have cost you money over this window. Improve reliability, lower your reliability commitment, or move **Confidence** toward **Low** (wider margin, larger fee) before listing. ### Large `largest_day_credit` diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 0d547e06..b0c43f27 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -79,7 +79,7 @@ On an outage day the renter is still charged the normal hourly rate, and you may - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. -- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting backtester results. Consider wider confidence or a more conservative reliability commitment until you have a few weeks of data. +- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting backtester results. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. ## SLA in plain language @@ -124,7 +124,7 @@ When a client rents an on-demand instance on your SLA-listed offer with a chosen - While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA fee** — including during downtime. Settlement credits for missed targets are calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA fee at the quoted allocation — **not** bandwidth. - Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. - **Strong reliability relative to the client's target** → you keep the SLA fee for that day. -- **Shortfalls** → credits flow to the client from your earnings (bounded by that day's covered compute). +- **Shortfalls** → credits flow to the client from your earnings. On a normal day that is up to that day's rental charges for the contract. See [SLA and GPU slicing](#sla-and-gpu-slicing) for the last-day caveat. Over many strong days, SLA fees can offset occasional credits, but a single bad day can exceed months of collected SLA fees — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. @@ -365,7 +365,7 @@ SLA fields example (existing listing, no extension). Same fields as the curl abo } ``` -This creates an offer with a reliability commitment of `0.99` and confidence spread `0.5`. Clients who search with `target_reliability` below your reliability commitment see a lower SLA fee than clients who choose a reliability target near your reliability commitment. +This updates the offer to a reliability commitment of `0.99` and confidence `sla_sigma_x` 0.5 (console **Medium**). Clients who search with `target_reliability` below your reliability commitment see a lower SLA fee than clients who choose a reliability target near your reliability commitment. `create_asks` is not a pure partial update. If you change only SLA fields, the platform re-validates the merged SLA parameters. Set `sla_r_claim` to `0` to disable SLA on an existing listing. Other omitted fields are not all kept: @@ -729,9 +729,9 @@ Clients receive credits tied to how far measured reliability falls below **their SLA fees are **much higher** when the client's target sits near your reliability commitment (little headroom). Prefer a reliability commitment you can sustain above the targets clients actually choose. -### You widen confidence (`sla_sigma_x` → 1.0) +### You set Confidence to Low (`sla_sigma_x` → 1.0) -Clients pay more because you admit greater uncertainty. Use this if your reliability history is volatile or the machine is new. +Clients pay a higher SLA fee, which gives you a larger cushion. Use **Low** if your reliability history is volatile or the machine is new. ### Scheduled maintenance @@ -801,7 +801,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Console** 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). - 2. Write down every field on **Set Pricing** (price, minimum GPUs, end date, storage price, bandwidth, **Reliability Commitment**, **Confidence**, reserved discount, and min bid). If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. + 2. Write down every field on **Set Pricing**: GPU price, minimum GPUs, storage price, bandwidth, reserved discount, min bid, whether the listing is **hidden**, the offer end date or auto-renew duration, **Reliability Commitment**, and **Confidence**. If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. From ec14d0247fd00ec9ac885dbbd74f69f2a911cfee Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 04:37:41 -0700 Subject: [PATCH 221/250] docs(sla): address doc-review consensus (cycle 166) Restore the backtester sample so break-even sits below the renter target it claims to illustrate. Co-authored-by: Cursor --- host/hosting-overview.mdx | 2 +- host/sla-backtester.mdx | 8 ++++---- host/sla-offers.mdx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index e2ed4ad8..7905e86f 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -235,7 +235,7 @@ Use `./vastai` instead of `vastai` when running from the install directory. CLI self-tests create **non-SLA** rentals (`vastai create instance` does not accept `target_reliability`). To test SLA contract terms on your own offer: 1. Create a separate client account (see above), or use REST from that account. -2. In the console Search filters, set a **Reliability target**, rent your own offer, and confirm an **SLA Fee** line before continuing — or `PUT /api/v0/asks/{id}/` with `target_reliability`. +2. In the console Search filters, set a **Reliability target** at or below your commitment, confirm the price breakdown shows an **SLA Fee** line, then rent. No **SLA Fee** line means the rental has no SLA. You can also `PUT /api/v0/asks/{id}/` with `target_reliability`. 3. Destroy the test instance when done. See [SLA](/guides/instances/choosing/sla-coverage) for renter-side details. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 09f7a0c4..00a65c2a 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -145,7 +145,7 @@ curl -s -H "Authorization: Bearer YOUR_API_KEY" \ **If you only read three things:** check `has_data` (if `false`, move the window toward the present or wait for more rental history), compare `r_eff` with `r_be`, then look at your [net SLA result and largest single-day credit](#summarize-with-jq). -A successful response looks like this (one `days` row shown). These numbers are the response to the `r_target=0.95` request above, not the baseline request that omits `r_target`. +A successful response looks like this (one `days` row shown). These numbers are an illustrative response to the baseline request above (`r_claim=0.99`, `p=0.6667`, `r_target=0.99`). They match the OpenAPI example. They are not the `$0.97/day` walkthrough on the host SLA page. ```json { @@ -155,7 +155,7 @@ A successful response looks like this (one `days` row shown). These numbers are "start_day": 20567, "end_day": 20657, "r_eff": 0.9987, - "r_be": 0.972, + "r_be": 0.9712, "days": [ { "day": 20567, @@ -168,8 +168,8 @@ A successful response looks like this (one `days` row shown). These numbers are ], "params": { "r_claim": 0.99, - "r_target": 0.95, - "beta": 0.30, + "r_target": 0.99, + "beta": 0.46, "p": 0.6667 } } diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index b0c43f27..634fb04e 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -701,7 +701,7 @@ The **reliability commitment** is your belief and pricing knob. The client's **r ### If the client's target is missed -A single bad day can wipe out weeks or months of SLA fees. In the example below, a day about 1–2 points below the client's target (~93–94% blended, not a day that exactly meets the target) costs about 44 days of collected SLA fees, and a full outage day costs about 88 days. Lower renter targets carry lower fees for a similar credit, so the ratio can be higher than this example. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. +A single bad day can wipe out weeks or months of SLA fees. In the example below, a day about 1–2 points below the client's target (~93–94% blended, not a day that exactly meets the target) costs about 44 days of collected SLA fees, and a full outage day costs about 88 days. These figures are illustrative. They do not come from the same pricing curve as the backtester sample. Use **Set Pricing → SLA** or the backtester for your machine's actual fee. Lower renter targets carry lower fees for a similar credit, so the ratio can be higher than this example. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. These scenarios show settlement when the blended measure falls **below** a 95% client target. They are illustrations, not typical strong days: From ded24befc8e780a72b3e7bc3f17804b0769ca20b Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 04:47:57 -0700 Subject: [PATCH 222/250] docs(sla): address doc-review consensus (cycle 167) Show console SLA credits as positive amounts, and stop a fee-skip from sounding like a permanent extension block. Co-authored-by: Cursor --- api-reference/openapi.yaml | 5 +++-- api-reference/openapi/yaml/show_earnings.yaml | 4 ++-- api-reference/permissions.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 10 +++++----- guides/reference/billing.mdx | 2 +- host/hosting-overview.mdx | 4 ++-- host/sla-offers.mdx | 14 +++++++++----- 7 files changed, 23 insertions(+), 18 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 3561cbaa..f0e840ef 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8002,8 +8002,9 @@ paths: in: path required: true schema: - type: integer - description: The ID of the user. + type: string + description: Ignored. The API key owner is always used. Pass `me` or your + numeric user id. - name: sday in: query schema: diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 0734088c..567965f8 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -24,8 +24,8 @@ paths: in: path required: true schema: - type: integer - description: The ID of the user. + type: string + description: Ignored. The API key owner is always used. Pass `me` or your numeric user id. - name: sday in: query schema: diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 72e27b57..4898f966 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -95,7 +95,7 @@ You can create scoped keys using: Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the host recipe. -**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. Charges and **Account → Billing → Charges** show the same net `type: "sla"` row. The console labels it **Service Credit** only when the amount is negative. +**Workflow summary:** Search, then REST rent with `target_reliability`, then verify on v1 instances. Charges and **Account → Billing → Charges** show the same net `type: "sla"` row. In the console, **Service Credit** is a positive amount and **SLA Fee** is a negative amount. In the API, a negative `amount` is a net credit. - Create a **dedicated** key for this workflow only. `misc` covers offer search **and** unrelated routes such as serverless endpoints and workergroups. Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 25964995..d3f04690 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -25,7 +25,7 @@ A few things people mix up: - The GPU bill does **not** stop during an outage. A credit is paid only when the blended measure falls below your target, usually after the next UTC midnight. A short outage that stays above the target is billed in full with no credit. - Filtering for SLA offers (`has_sla`, SLA-enabled), or a CLI or API search, does **not** turn on an SLA. Setting **Reliability target** in the console Search filters and then clicking **RENT**, or sending `target_reliability` on REST rent, does. The CLI cannot turn SLA on. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. -- If the Search offer has **no SLA Fee line**, you do not have an SLA. On an instance, that line appears only while the instance is **running**. In **Account → Billing → Charges** the settlement row is labeled **Service Credit** only when the net amount is negative, and **SLA Fee** otherwise. In API responses the hourly amount is `slaPremiumPerHour`. +- If the Search offer has **no SLA Fee line**, you do not have an SLA. On an instance, that line appears only while the instance is **running**. In **Account → Billing → Charges**, **Service Credit** is shown as a positive amount (`+$`) and **SLA Fee** as a negative amount (`−$`). The API `amount` has the opposite sign. In API responses the hourly amount is `slaPremiumPerHour`. Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). @@ -38,7 +38,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. Write down **SLA Fee/hr**. You need it later to check credits, and the line is hidden while the instance is loading, stopped, or offline. Then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. -6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. A negative net is labeled **Service Credit**. Any other net is labeled **SLA Fee**. +6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row closer to zero than your usual daily fee. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -187,7 +187,7 @@ Always compare the total hourly price: the offer **Price** in the console, whose -Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. Charges and the console Charges tab show the same net `type: "sla"` row (SLA fee minus any service credit). The console labels it **Service Credit** only when the amount is negative. Invoices and credit webhooks do not include that row. +Search quotes SLA; renting with SLA requires REST (or the console) with `target_reliability`. The CLI and published SDK cannot enable SLA on rent. Charges and the console Charges tab show the same net `type: "sla"` row. In the console, **Service Credit** is a positive amount and **SLA Fee** is a negative amount. In the API, a negative `amount` is a net credit and a positive `amount` is a net fee. Invoices and credit webhooks do not include that row. @@ -413,7 +413,7 @@ Production settlement uses the multi-window reliability blend described above, n ### Settlement timing - Settlement runs **once per day** for the previous billing day (UTC). -- Service credits post to your **account balance**. In **Account → Billing → Charges**, a negative net SLA row is labeled **Service Credit**. Any other net is labeled **SLA Fee**. `GET /api/v0/charges/` returns that same net as `type: "sla"`. Do not use invoices to reconcile SLA credits. +- Service credits post to your **account balance**. In **Account → Billing → Charges**, **Service Credit** is shown as a positive amount (`+$`) and **SLA Fee** as a negative amount (`−$`). `GET /api/v0/charges/` returns the same row as `type: "sla"` with the opposite sign: a negative `amount` is a net credit and a positive `amount` is a net fee. Do not use invoices to reconcile SLA credits. - When your contract ends, any remaining unsettled days are resolved at close. ## If your instance goes down @@ -489,7 +489,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing → Charges**. A negative net SLA row is labeled **Service Credit**. A smaller but still positive **SLA Fee** row means a partial credit. Compare it with the **SLA Fee/hr** you wrote down at rent (console quick start step 4) times every hour the contract existed that UTC day, including downtime. The Charges API returns the same net. Invoices do not. You cannot see the measured reliability for that day in the console or the API. +**Console:** After UTC settlement, open **Account → Billing → Charges**. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row closer to zero than your usual daily fee. Compare the size of that row with the **SLA Fee/hr** you wrote down at rent (console quick start step 4) times every hour the contract existed that UTC day, including downtime. The Charges API returns the same row with the opposite sign. Invoices do not. You cannot see the measured reliability for that day in the console or the API. **API integrators:** Use the same Charges row as [Settlement timing](#settlement-timing). The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. A row below the fee you expected means a credit was applied. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index f6e63b31..5f9250df 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -150,7 +150,7 @@ At the bottom of your billing page, you will find an itemized table of your tran ![Invoices tab of the Transaction History table](/images/transaction-history-table-invoices.png) -You can also click the **Charges** tab to see an itemized table of all charges from your instances, storage volumes, and serverless workers. Clicking the dropdown arrow on any of these items will display a more complete breakdown of those charges by type, including GPU usage, reserved disk storage, and upload/download usage. SLA rentals add one net row for the SLA fee minus any service credit. That row is labeled **Service Credit** only when the amount is negative, and **SLA Fee** otherwise. +You can also click the **Charges** tab to see an itemized table of all charges from your instances, storage volumes, and serverless workers. Clicking the dropdown arrow on any of these items will display a more complete breakdown of those charges by type, including GPU usage, reserved disk storage, and upload/download usage. SLA rentals add one net row. In the console, **Service Credit** is a positive amount and **SLA Fee** is a negative amount. The API `amount` has the opposite sign. ![Charges tab of the Transaction History table](/images/transaction-history-table-charges.png) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 7905e86f..6ec51131 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (**Reliability Commitment**, or **Confidence**, which is the fee margin) that would raise a contract's SLA fee means that contract is **not extended** by that request. A contract's SLA terms are locked when it is rented and never change. A contract skipped only for that fee change can still be extended by a later request. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (**Reliability Commitment**, or **Confidence**, which is the fee margin) that would raise a contract's SLA fee means that contract is **not extended** by that request. A contract's SLA terms are locked when it is rented and never change. A contract skipped only for that fee change is extended by a later request only if your settings at that time no longer raise its SLA fee. Unlike a price increase, nothing is recorded that keeps blocking it. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. @@ -195,7 +195,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. Lowering your **Reliability Commitment** or moving **Confidence** toward **Low** in that same request also skips any SLA contract whose fee would rise. A later request can still extend it. For SLA rentals, an extension also extends service-credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. Lowering your **Reliability Commitment** or moving **Confidence** toward **Low** in that same request also skips any SLA contract whose fee would rise. A later request extends it only if your settings no longer raise its SLA fee. For SLA rentals, an extension also extends service-credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). ## Testing your own machine diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 634fb04e..bceb023b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -124,7 +124,7 @@ When a client rents an on-demand instance on your SLA-listed offer with a chosen - While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA fee** — including during downtime. Settlement credits for missed targets are calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA fee at the quoted allocation — **not** bandwidth. - Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. - **Strong reliability relative to the client's target** → you keep the SLA fee for that day. -- **Shortfalls** → credits flow to the client from your earnings. On a normal day that is up to that day's rental charges for the contract. See [SLA and GPU slicing](#sla-and-gpu-slicing) for the last-day caveat. +- **Shortfalls** → credits flow to the client from your earnings. On a normal day, the credit can be as large as that day's rental charges for the contract. See [SLA and GPU slicing](#sla-and-gpu-slicing) for the last-day caveat. Over many strong days, SLA fees can offset occasional credits, but a single bad day can exceed months of collected SLA fees — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. @@ -233,7 +233,7 @@ On a listed machine, moving the offer end date later extends every shorter activ - **Extends shorter rentals:** a request that sends `end_date` or `duration` at the same or a lower GPU, disk, and bandwidth price. - **Skips that contract:** the request raises the GPU, disk, or bandwidth price. For some renters this records a pending price increase, and later extension requests also skip that contract until the renter accepts or declines it. A request that would raise the contract's SLA fee, or that fails an SLA check (for example `sla_r_claim: 0` or a reliability commitment below that contract's target), also skips it. The contract keeps its end date and is missing from `upd_contracts`. -- **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A skip caused only by an SLA-fee change does not stop a later request. A pending price increase does. +- **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A skip caused only by an SLA-fee change does not record a lasting block. A later request extends that contract only if your settings no longer raise its SLA fee. A pending price increase does keep blocking later extensions. - **You cannot see each contract's end date in the documented API.** **Host → Machines** shows the latest rental end date on the machine. You cannot confirm in advance which rentals a later `end_date` will extend. Changing the reliability commitment or Confidence does not change the SLA fee already locked on a contract. Only new rentals pick up the new terms. Extending a contract re-checks it against your current settings. If those settings would raise that renter's SLA fee, the contract is not extended and keeps its original end date. Hosts do not set the SLA fee. It changes when you change the reliability commitment or Confidence (a wider margin, console **Low**, raises the fee at a given target). @@ -309,10 +309,10 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -d '{"machine": 12345, "price_disk": CURRENT_STORAGE_PRICE, "price_inetu": CURRENT_INET_UP, "price_inetd": CURRENT_INET_DOWN, "credit_discount_max": CURRENT_DISCOUNT, "min_chunk": CURRENT_MIN_CHUNK, "vol_size": 0, "hidden_listing": CURRENT_HIDDEN, "sla_r_claim": 0.99, "sla_sigma_x": 0.5}' ``` -Replace `CURRENT_STORAGE_PRICE`, `CURRENT_INET_UP`, `CURRENT_INET_DOWN`, `CURRENT_DISCOUNT`, and `CURRENT_MIN_CHUNK` from `vastai show machines --raw` (`listed_storage_cost`, `listed_inet_up_cost`, `listed_inet_down_cost`, `credit_discount_max`, and `listed_min_gpu_count`). On an existing ask, omit `price_min_bid`. The stored minimum is kept. Do not copy `min_bid_price` into the body. That value is net of the platform fee, and resending it shifts the minimum on every update. After an unlist, send the `price_min_bid` you wrote down yourself. `show machines` does not report hidden status. Set `CURRENT_HIDDEN` from your own notes or **Set Pricing**. Sending `false` for a hidden listing makes it public. An unedited paste is not valid JSON. Include bandwidth and the discount in the body so a new ask does not publish at $0 bandwidth or the 0.4 discount default. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Check those fields in the response. Send `end_date` only in the full listing update below, when you mean to extend. +Replace `CURRENT_STORAGE_PRICE`, `CURRENT_INET_UP`, `CURRENT_INET_DOWN`, `CURRENT_DISCOUNT`, and `CURRENT_MIN_CHUNK` from `vastai show machines --raw` (`listed_storage_cost`, `listed_inet_up_cost`, `listed_inet_down_cost`, `credit_discount_max`, and `listed_min_gpu_count`). On an existing ask, omit `price_min_bid`. The stored minimum is kept. Do not copy `min_bid_price` into the body. That value is net of the platform fee, and resending it shifts the minimum on every update. After an unlist, send the `price_min_bid` you wrote down yourself. `show machines` does not report hidden status. Set `CURRENT_HIDDEN` from your own notes or **Set Pricing**. Sending `false` for a hidden listing makes it public. An unedited paste is not valid JSON. Include bandwidth and the discount in the body so a new ask does not publish at $0 bandwidth or the 0.4 discount default. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Confirm `price_inetu`, `price_inetd`, `credit_discount_max`, `price_min_bid`, and `sla_sigma_x` on that ask. A new ask resets omitted values to their defaults. Send `end_date` only in the full listing update below, when you mean to extend. -Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes the reliability commitment or Confidence in a way that would raise that contract's SLA fee. A reliability-commitment or Confidence change does **not** prevent a later extension (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). +Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes the reliability commitment or Confidence in a way that would raise that contract's SLA fee. A reliability-commitment or Confidence change does not record a lasting block. A later request extends that contract only if your settings no longer raise its SLA fee (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). #### Full listing update (existing ask) @@ -410,7 +410,7 @@ Use this loop only to restore SLA offers that no longer appear in search on mach Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. No documented API shows each rental's end date, so you cannot confirm in advance which rentals a later `end_date` will extend. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). -The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute for the account, not for each API key. See [How rate limits are applied](/api-reference/rate-limits-and-errors#how-rate-limits-are-applied). The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. +The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute for the account, not for each API key. See [How rate limits are applied](/api-reference/rate-limits-and-errors#how-rate-limits-are-applied). The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped, unless the error is `search_quota_exceeded`. That daily quota can take hours to reset, so the loop stops. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. `show machines` returns confidence only as a label. Set `SIGMA_MAP` (`id=σ`, space-separated) from your own record before `DRY_RUN=0`. A live run skips any machine that is not in the map, because a new ask would otherwise reset `sla_sigma_x` to `0.5`. Resending the same σ on an existing ask is harmless. The post-run `WARN` is only a backstop. @@ -539,6 +539,10 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do sleep 6 out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --retry 1 --api-key "$SEARCH_API_KEY" 2>"$BTERR") if ! printf '%s' "$out" | jq -e 'type == "array"' >/dev/null; then + if grep -q 'search_quota_exceeded' "$BTERR"; then + echo "ABORT: daily search quota exhausted (search_quota_exceeded). Retry-After can be hours. Re-run later." >&2 + exit 1 + fi echo "skip $id: search failed (missing misc permission or HTTP 429); see $BTERR" >&2 continue fi From b7e615f51fec1b2405b84c294de5bc4fd3ba8fe2 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 05:00:56 -0700 Subject: [PATCH 223/250] docs(sla): address doc-review consensus (cycle 168) Charges reconciliation needs billing_read, and the CLI command is schedule maint, not schedule maintenance. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 8 ++++---- host/set-maintenance-window.mdx | 2 +- host/sla-offers.mdx | 2 +- host/upgrade-docker-and-packages.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d3f04690..0b86d33f 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -38,7 +38,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. Write down **SLA Fee/hr**. You need it later to check credits, and the line is hidden while the instance is loading, stopped, or offline. Then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. -6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row closer to zero than your usual daily fee. +6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row smaller than your SLA Fee/hr times the hours the contract existed that UTC day. The first and last days of a rental are partial, so a smaller row on those days is not by itself a credit. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -275,7 +275,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/asks/OFFER_ID/" \ `template_hash_id` is the content hash of a saved template. Include `template_hash_id` to rent from the template. Add `image` only when you want to override the template image. A request needs at least one of those fields. A template rent can send `template_hash_id` alone. Request fields override template defaults. `disk` below 8 GB is raised to 8 GB with no error. Omitting `disk`, or sending `0`, rents 10 GB. A CLI quote at the 5 GiB default will not match the billed storage. Rent returns `invalid_price` when the offer's GPU price exceeds the platform maximum, not because `target_reliability` changed. Re-search and use a fresh offer ID. See [Create Instance](/api-reference/instances/create-instance). -**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances --raw`). These three categories are the minimum for search → rent → verify. See [Authentication](/api-reference/authentication) and [Renter SLA scoped-key recipe](/api-reference/permissions#renter-sla-scoped-key-recipe). +**API key permissions:** create a scoped key with `misc` (search/bundles), `instance_write` (create-instance), and `instance_read` (verify with `GET /api/v1/instances/` or `vastai show instances --raw`). These three categories are the minimum for search → rent → verify. Add `billing_read` if you will reconcile SLA rows on Charges. The minimum key above cannot call `GET /api/v0/charges/`. See [Authentication](/api-reference/authentication) and [Renter SLA scoped-key recipe](/api-reference/permissions#renter-sla-scoped-key-recipe). **3. Verify.** Save `new_contract` from the rent response. Look that contract up with URL-encoded `select_filters` (`id` is a filterable column): @@ -303,7 +303,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. If `next_token` is not `null`, repeat the request with `after_token` set to that value before you treat a missing `sla` item as unsettled. `limit` defaults to 100, so a busy account can put the contract on a later page. ```bash -# YOUR_API_KEY is the same key as the earlier steps. NEW_CONTRACT is the contract id from the rent response. +# YOUR_API_KEY must also have billing_read. The minimum search → rent → verify key cannot call Charges. NEW_CONTRACT is the contract id from the rent response. curl -s -G "https://console.vast.ai/api/v0/charges/" \ -H "Authorization: Bearer YOUR_API_KEY" \ --data-urlencode 'select_filters={"day":{"gte":1767225600,"lte":1767311999}}' \ @@ -489,7 +489,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing → Charges**. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row closer to zero than your usual daily fee. Compare the size of that row with the **SLA Fee/hr** you wrote down at rent (console quick start step 4) times every hour the contract existed that UTC day, including downtime. The Charges API returns the same row with the opposite sign. Invoices do not. You cannot see the measured reliability for that day in the console or the API. +**Console:** After UTC settlement, open **Account → Billing → Charges**. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row smaller than your SLA Fee/hr times the hours the contract existed that UTC day (console quick start step 4). The first and last days are partial, so a smaller row on those days is not by itself a credit. The Charges API returns the same row with the opposite sign. Invoices do not. You cannot see the measured reliability for that day in the console or the API. **API integrators:** Use the same Charges row as [Settlement timing](#settlement-timing). The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. A row below the fee you expected means a credit was applied. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/host/set-maintenance-window.mdx b/host/set-maintenance-window.mdx index 7bee9c5e..1086b6c9 100644 --- a/host/set-maintenance-window.mdx +++ b/host/set-maintenance-window.mdx @@ -185,7 +185,7 @@ page — a window set to **Updates** reads as `software` here. - [Host notifications](/host/notifications) — control how maintenance confirmations reach you -- [`vastai schedule maintenance`](/host/cli/schedule-maint) — schedule a window +- [`vastai schedule maint`](/host/cli/schedule-maint) — schedule a window from the CLI - [`vastai show maints`](/host/cli/show-maints) — list scheduled windows - [`vastai cancel maint`](/host/cli/cancel-maint) — cancel a machine's windows diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index bceb023b..f04a08fd 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -48,7 +48,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Confirm an **SLA Fee** line. If that line is missing on every offer, SLA may be off platform-wide. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - - **API users:** search with `verified=any` and confirm `expected_reliability` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). + - **API users:** search with `verified=any` and confirm `expected_reliability` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). The CLI may print `Warning: Unrecognized field` for `has_sla` and `expected_reliability`. That warning is harmless: the filter is still sent. On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). ## Before you enable SLA diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index 9f00b714..5f1b019e 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -82,7 +82,7 @@ with the command above, then schedule maintenance so renters get a notification with your window. Do not stop or delete client containers. ```bash -vastai schedule maintenance id [--sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY] +vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY] ``` See [`vastai schedule maint`](/host/cli/schedule-maint). When the window starts, diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 1bd46acf..4d11e3b4 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -8,7 +8,7 @@ Schedule an upcoming maintenance window vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY ``` -`schedule maintenance` is an alias for `schedule maint` if your CLI build supports both spellings. Prefer `maint`. Requires `machine_write` on scoped API keys — see [Permissions](/api-reference/permissions). +Use `vastai schedule maint`. Requires `machine_write` on scoped API keys — see [Permissions](/api-reference/permissions). The CLI prints the window and asks `Continue? [y/n]` before it sends the request. In scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call the [REST endpoint](/api-reference/machines/schedule-maint) directly. From 38c8e3a4324aaf7bd720eb6030ef5eba1b2d410b Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 05:01:03 -0700 Subject: [PATCH 224/250] docs(sla): address doc-review consensus (cycle 168) Note that the CLI unrecognized-field warning on has_sla does not mean the filter was dropped. Co-authored-by: Cursor --- host/sla-offers.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index f04a08fd..c2d733a0 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -671,7 +671,7 @@ When SLA is enabled on an offer, clients see: **Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the reliability commitment. The published reliability commitment appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, use `has_sla=true` or filter on `expected_reliability > 0`; do not use the `reliability` filter as an SLA selector. -Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand). Match disk allocation before comparing `dph_total` across channels (CLI default is often 5 GiB; console Search is typically 10 GB; REST examples often use 8 GB `allocated_storage`): +Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand). The CLI may print `Warning: Unrecognized field` for `has_sla`. That warning is harmless: the filter is still sent. Match disk allocation before comparing `dph_total` across channels (CLI default is often 5 GiB; console Search is typically 10 GB; REST examples often use 8 GB `allocated_storage`): ```bash vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw \ From 20c34d6bb838e1edd8723940557accea7024ea9c Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 05:13:24 -0700 Subject: [PATCH 225/250] docs(sla): address doc-review consensus (cycle 169) Tell SLA hosts that a 24-hour maintenance default is not full forgiveness, and that a CLI relist drops the SLA. Co-authored-by: Cursor --- api-reference/openapi.yaml | 14 +++++++++++--- api-reference/openapi/yaml/show_charges.yaml | 9 +++++++-- api-reference/permissions.mdx | 2 +- host/set-maintenance-window.mdx | 10 ++++++++-- host/sla-offers.mdx | 8 ++++++-- host/upgrade-docker-and-packages.mdx | 9 +++------ snippets/host/cli/list-machine.mdx | 2 +- 7 files changed, 37 insertions(+), 17 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index f0e840ef..32d07336 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -7365,9 +7365,10 @@ paths: /api/v0/charges: get: summary: show charges - description: 'Shows charges per instance, including GPU, storage, and bandwidth. - For invoice/payment records (Stripe top-ups, transfers, payouts), use [show - invoices](/api-reference/billing/show-invoices) instead. + description: 'Shows charges per instance, including GPU, storage, bandwidth, + and the net SLA row (`type: "sla"`). For invoice/payment records (Stripe top-ups, + transfers, payouts), use [show invoices](/api-reference/billing/show-invoices) + instead. CLI: `vastai show invoices-v1 --charges`' @@ -7562,6 +7563,13 @@ paths: amount: type: number format: float + description: 'Charge amount for this item. For type + "sla", this is the SLA fee minus any service credit + for the settled UTC day. A positive amount is a + net fee. A negative amount is a net credit. The + console Charges tab shows the opposite sign. + + ' example: 37.344 metadata: type: object diff --git a/api-reference/openapi/yaml/show_charges.yaml b/api-reference/openapi/yaml/show_charges.yaml index 3e4f7136..9f278fee 100644 --- a/api-reference/openapi/yaml/show_charges.yaml +++ b/api-reference/openapi/yaml/show_charges.yaml @@ -1,7 +1,7 @@ openapi: 3.0.0 info: title: Vast.ai Show Charges API - description: API endpoint to retrieve per-instance billing charges (GPU, storage, and bandwidth). + description: API endpoint to retrieve per-instance billing charges (GPU, storage, bandwidth, and the net SLA row). version: 1.0.0 servers: @@ -13,7 +13,7 @@ paths: get: summary: show charges description: | - Shows charges per instance, including GPU, storage, and bandwidth. For invoice/payment records (Stripe top-ups, transfers, payouts), use [show invoices](/api-reference/billing/show-invoices) instead. + Shows charges per instance, including GPU, storage, bandwidth, and the net SLA row (`type: "sla"`). For invoice/payment records (Stripe top-ups, transfers, payouts), use [show invoices](/api-reference/billing/show-invoices) instead. CLI: `vastai show invoices-v1 --charges` security: @@ -171,6 +171,11 @@ paths: amount: type: number format: float + description: > + Charge amount for this item. For type "sla", this is the SLA fee + minus any service credit for the settled UTC day. A positive amount + is a net fee. A negative amount is a net credit. The console Charges + tab shows the opposite sign. example: 37.344 metadata: type: object diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 4898f966..4daffadd 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -131,7 +131,7 @@ curl -G "https://console.vast.ai/api/v0/charges/" \ ``` -Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). An amount smaller than the SLA fee you expected, or a negative amount, means a credit was applied. The contract row can appear before settlement. Its `sla` item is absent until that day settles. If `next_token` is not `null`, repeat the request with `after_token` before you treat a missing `sla` item as unsettled. +Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). A negative amount, or one smaller than your SLA fee per hour times the hours the contract existed that day, can mean a credit was applied. The first and last days of a rental are partial. On a day with a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. See [Billing reconciliation](/guides/instances/choosing/sla-coverage#billing-reconciliation). The contract row can appear before settlement. Its `sla` item is absent until that day settles. If `next_token` is not `null`, repeat the request with `after_token` before you treat a missing `sla` item as unsettled. diff --git a/host/set-maintenance-window.mdx b/host/set-maintenance-window.mdx index 1086b6c9..0e119314 100644 --- a/host/set-maintenance-window.mdx +++ b/host/set-maintenance-window.mdx @@ -12,6 +12,10 @@ Scheduling a window is a notification, not an action. It does not stop instances unlist the machine, or block new rentals. You still take the machine down yourself when the window arrives. + +**Offering an SLA?** More notice forgives more of a window, and longer windows are forgiven less. The 24-hour default start is not a forgiveness threshold, and notice is not guaranteed to forgive the downtime fully. Schedule as far ahead as you can and keep the duration as short as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). + + The screenshots on this page use the redesigned **Machines** page, which is currently in Early Access. See [Using the classic Machines page](#using-the-classic-machines-page) @@ -47,7 +51,8 @@ reason. Fill in all three fields: - **Maintenance start** — the date and time the machine goes down. It - defaults to 24 hours from now. + defaults to 24 hours from now. On an SLA machine that default is not a + forgiveness cutoff. Schedule further ahead when you can. - **Duration (hours)** — how long the machine will be unavailable, as a whole number of hours. - **Reason** — what the maintenance is for. See @@ -98,7 +103,8 @@ switch — you can schedule a single window for all of them in one pass. The list below the form gains a **Machine** column so you can tell the windows apart, and a summary tells you which machines succeeded and which - failed. + failed. Retry with only the failed machines selected. Adding the window + again on a machine that already succeeded creates a duplicate. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index c2d733a0..92e76acd 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -38,7 +38,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist -1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [Auto-renew and SLA](#sla-on-extended-contracts) before you enable SLA. +1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave **Reliability Commitment** (the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. @@ -229,6 +229,10 @@ For planning, assume a bad day can cost up to one full day of covered compute fo ### SLA on extended contracts +**In the console:** moving the offer end date later, or leaving auto-renew on, extends active SLA rentals and your credit exposure. To limit that, set a fixed end date or unlist. + +**API detail (`create_asks`):** + On a listed machine, moving the offer end date later extends every shorter active SLA rental and your credit exposure. To avoid that, unlist instead of extending. Auto-renew (`duration` or `vastai list machine -l`) keeps moving that end date forward and extends active SLA rentals with it. - **Extends shorter rentals:** a request that sends `end_date` or `duration` at the same or a lower GPU, disk, and bandwidth price. @@ -775,7 +779,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ `sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. There is no public REST endpoint for reading maintenance windows. Even if you schedule or cancel over REST, confirm the result with `vastai show maints --ids 'MACHINE_ID' --raw` or on the console **Maintenance** tab. Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. Retries must not create a duplicate of the same one. See [Schedule Maintenance](/api-reference/machines/schedule-maint). -**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. In scripts, pass `--retry 1` on `schedule maint` and `cancel maint`. A retried PUT can create a second window if the first one was stored and the response was lost. Confirm exactly one window before you schedule the next machine. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. To change one window, cancel, then create again every window you still want, as far ahead as you can, and confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). +**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. In scripts, pass `--retry 1` on `schedule maint` and `cancel maint`. A retried PUT can create a second window if the first one was stored and the response was lost. Confirm exactly one window before you schedule the next machine. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. In the console, **✕** on a row cancels that one window. With the CLI or REST, `cancel maint` removes every window on the machine. To change one window from the CLI, cancel all of them, then create again each window you still want. A new window starts its notice clock over. Confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index 5f1b019e..3521e973 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -77,12 +77,10 @@ vastai unlist machine See [`vastai unlist machine`](/host/cli/unlist-machine). -**If anything is rented and you still want to upgrade:** unlist the machine -with the command above, then schedule maintenance so renters get a notification -with your window. Do not stop or delete client containers. +**If anything is rented and you still want to upgrade:** stay listed and schedule a maintenance window instead of unlisting. On an SLA machine, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Do not stop or delete client containers. ```bash -vastai schedule maint id [--sdate START_DATE --duration DURATION --maintenance_category MAINTENANCE_CATEGORY] +vastai schedule maint MACHINE_ID --sdate UNIX_UTC --duration HOURS --maintenance_category software ``` See [`vastai schedule maint`](/host/cli/schedule-maint). When the window starts, @@ -555,8 +553,7 @@ Canceled hold on linux-image-generic-hwe-24.04. ### Relist -Relist from the [Machines page](https://cloud.vast.ai/host/machines/) or with -your usual [`vastai list machine`](/host/cli/list-machine) command. After 2 to 3 +Relist from the [Machines page](https://cloud.vast.ai/host/machines/). If the machine had an SLA, use **Set Pricing → SLA → Save → LIST** and re-enter every field you wrote down. `vastai list machine` creates the ask without SLA and can reset bandwidth and other fields. See the [`list machine` cautions](/host/cli/list-machine). After 2 to 3 minutes: ```bash diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index b2f29c50..0befb4d9 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -18,7 +18,7 @@ On an existing listing, omitted GPU price, bandwidth prices, reserved discount, - **Passing `-e` or `-l` can extend active rentals,** including SLA contracts. Normal CLI output does not print that. Pass `--raw` and read `.results[0].upd_contracts`. - **After an unlist, the relist is a new ask.** Omitted `-u`/`-d` publish $0 bandwidth, omitted `-r` becomes `0.4`, and omitted `-m` becomes 1. Pass all of them. -- **`-m` defaults to 1.** On an existing listing that has no effect. On a first listing, or a relist after unlist, it splits the machine into single-GPU offers, and each one can be its own SLA contract. Always pass `-m` with the min GPU count you intend. +- **`-m` defaults to 1.** Omitting `-m` has no effect on an existing listing. On a first listing, or a relist after unlist, it splits the machine into single-GPU offers, and each one can be its own SLA contract. Always pass `-m` with the min GPU count you intend. - **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores listed SLA offers that are missing from search, on machines with no rentals. It does not change prices. A hidden listing is also missing from search, so set `HIDDEN_IDS` or the live run makes it public. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. From dc8ab0a4e4785ff9adf62442c80cbe7f8bbf2af3 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 05:22:36 -0700 Subject: [PATCH 226/250] docs(sla): address doc-review consensus (cycle 170) Save SLA listing terms before an upgrade unlist, and stop the weekly earnings window on yesterday. Co-authored-by: Cursor --- api-reference/openapi.yaml | 4 +++- api-reference/openapi/yaml/show_earnings.yaml | 2 +- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-offers.mdx | 5 +++-- host/upgrade-docker-and-packages.mdx | 9 ++++----- snippets/host/cli/list-machine.mdx | 2 +- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 32d07336..92474cb1 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8064,7 +8064,9 @@ paths: type: number total_sla: type: number - description: Net SLA earnings over the requested window. + description: Sum of sla_earn for the window (from per_day + when present, otherwise per_machine). Escrow released to + the host, not fees minus credits. username: type: string email: diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 567965f8..07923226 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -71,7 +71,7 @@ paths: type: number total_sla: type: number - description: Net SLA earnings over the requested window. + description: Sum of sla_earn for the window (from per_day when present, otherwise per_machine). Escrow released to the host, not fees minus credits. username: type: string email: diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 79d6690c..354094a0 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -56,7 +56,7 @@ All stats shown are the portion of the total machine rented. - DLPERF score: A custom deep learning performance score - Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. When you set a **Reliability target**, the breakdown on SLA listings also shows an **SLA Fee** line — see [SLA](/guides/instances/choosing/sla-coverage). - Max Duration: The maximum length of a rental contract on this machine -- Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host reliability commitment. +- Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host reliability commitment. On an SLA offer that commitment is **expected reliability** (not this score). Your **Reliability target** must be at or below it. - Rental Option: RENT button - **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA Fee** line in the price breakdown. An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 0b86d33f..67172dd0 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -38,7 +38,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. Write down **SLA Fee/hr**. You need it later to check credits, and the line is hidden while the instance is loading, stopped, or offline. Then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. -6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row smaller than your SLA Fee/hr times the hours the contract existed that UTC day. The first and last days of a rental are partial, so a smaller row on those days is not by itself a credit. +6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row closer to zero than your SLA Fee/hr times the hours the contract existed that UTC day. The first and last days of a rental are partial, so a row closer to zero on those days is not by itself a credit. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -489,7 +489,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing → Charges**. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row smaller than your SLA Fee/hr times the hours the contract existed that UTC day (console quick start step 4). The first and last days are partial, so a smaller row on those days is not by itself a credit. The Charges API returns the same row with the opposite sign. Invoices do not. You cannot see the measured reliability for that day in the console or the API. +**Console:** After UTC settlement, open **Account → Billing → Charges**. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row closer to zero than your SLA Fee/hr times the hours the contract existed that UTC day. The first and last days are partial, so a row closer to zero on those days is not by itself a credit. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. The Charges API returns the same row with the opposite sign. Invoices do not. You cannot see the measured reliability for that day in the console or the API. **API integrators:** Use the same Charges row as [Settlement timing](#settlement-timing). The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. A row below the fee you expected means a credit was applied. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 92e76acd..1e08ad3f 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -851,6 +851,7 @@ After you enable SLA, charges and credits settle on UTC (Coordinated Universal T - The backtester under-counts days that already had SLA rentals, so it cannot confirm a past credit. See [Simulation limits](/host/sla-backtester#simulation-limits). - SLA-contract compute is not included in `gpu_earn`, `sto_earn`, or bandwidth earnings. `sla_earn` is negative only when a prior day is corrected. - `per_day[].sla_earn` is fleet-wide even when you pass a machine ID. Use `per_machine[].sla_earn` for one machine. +- `summary.total_sla` adds up `sla_earn` for the window (from `per_day` when that list is present, otherwise from `per_machine`). Like `sla_earn`, it is escrow released to you, not fees minus credits. ### Console (fleet totals only) @@ -871,13 +872,13 @@ SLA settlement does not emit a host webhook. Machine offline and error alerts do **Linux (GNU date):** ```bash -vastai show earnings --machine_id --start_date "$(date -u -d '7 days ago' +%F)T00:00:00Z" --end_date "$(date -u +%F)T00:00:00Z" +vastai show earnings --machine_id --start_date "$(date -u -d '7 days ago' +%F)T00:00:00Z" --end_date "$(date -u -d 'yesterday' +%F)T00:00:00Z" ``` **macOS:** ```bash -vastai show earnings --machine_id --start_date "$(date -u -v-7d +%F)T00:00:00Z" --end_date "$(date -u +%F)T00:00:00Z" +vastai show earnings --machine_id --start_date "$(date -u -v-7d +%F)T00:00:00Z" --end_date "$(date -u -v-1d +%F)T00:00:00Z" ``` Keep the `T00:00:00Z` suffix: the CLI parses bare dates such as `2026-07-24` in the local time zone of the computer running the CLI, not UTC, so append `T00:00:00Z` for an exact UTC day. On Windows, use WSL or the API example below. See [`show earnings`](/cli/reference/show-earnings) for all options. diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index 3521e973..b5b805c4 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -6,9 +6,9 @@ description: "Safely upgrade Docker, containerd, the NVIDIA stack, and other sys -Before you start: [schedule a maintenance window](/host/set-maintenance-window) at least **48 hours** in advance. +If the machine has any rental, running or stopped, [schedule a maintenance window](/host/set-maintenance-window) before you start, as far ahead as you can. 48 hours is a courtesy, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. If nothing is rented, go to step 1. -You are responsible for the maintenance and any resulting interruption. Work performed outside the scheduled maintenance window may be treated as an **operational failure**. +You are responsible for the maintenance and any resulting interruption. If you are unsure whether this operation could cause data loss, stop here. @@ -67,8 +67,7 @@ Occ: 0 #Stored: D: 0, I: 0, R: 0 ``` -No `C.` lines and all three at 0 means the machine is free. Unlist it so nobody -rents it while Docker or the GPUs are down, then continue at step 2: +No `C.` lines and all three at 0 means the machine is free. If it has an SLA, write down every **Set Pricing** field first (GPU, storage, and bandwidth prices, minimum GPUs, end date, reserved discount, min bid, whether the listing is hidden, **Reliability Commitment**, and **Confidence**). Unlisting drops the SLA ask, and `show machines` will not return the exact confidence afterward. See [Severe outage](/host/sla-offers#severe-outage). Then unlist so nobody rents it while Docker or the GPUs are down, and continue at step 2: ```bash vastai unlist machine @@ -77,7 +76,7 @@ vastai unlist machine See [`vastai unlist machine`](/host/cli/unlist-machine). -**If anything is rented and you still want to upgrade:** stay listed and schedule a maintenance window instead of unlisting. On an SLA machine, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Do not stop or delete client containers. +**If anything is rented and you still want to upgrade:** stay listed and schedule a maintenance window instead of unlisting. A window does not stop new rentals. If you need to stop them, save the listing terms above, then unlist. On an SLA machine, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Do not stop or delete client containers. ```bash vastai schedule maint MACHINE_ID --sdate UNIX_UTC --duration HOURS --maintenance_category software diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 0befb4d9..28dead7a 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -18,7 +18,7 @@ On an existing listing, omitted GPU price, bandwidth prices, reserved discount, - **Passing `-e` or `-l` can extend active rentals,** including SLA contracts. Normal CLI output does not print that. Pass `--raw` and read `.results[0].upd_contracts`. - **After an unlist, the relist is a new ask.** Omitted `-u`/`-d` publish $0 bandwidth, omitted `-r` becomes `0.4`, and omitted `-m` becomes 1. Pass all of them. -- **`-m` defaults to 1.** Omitting `-m` has no effect on an existing listing. On a first listing, or a relist after unlist, it splits the machine into single-GPU offers, and each one can be its own SLA contract. Always pass `-m` with the min GPU count you intend. +- **`-m` defaults to 1.** The CLI always sends `min_chunk`, using 1 when you omit `-m`. On an existing listing the server does not use that value to resplit the machine. On a first listing, or a relist after unlist, 1 splits the machine into single-GPU offers, and each one can be its own SLA contract. Always pass `-m` with the min GPU count you intend. - **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores listed SLA offers that are missing from search, on machines with no rentals. It does not change prices. A hidden listing is also missing from search, so set `HIDDEN_IDS` or the live run makes it public. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). Update hidden SLA listings through REST. From 235bd796408d05dd2293bfdab83dc7867a5cb656 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 05:37:20 -0700 Subject: [PATCH 227/250] docs(sla): address doc-review consensus (cycle 171) Stop combining has_sla with expected_reliability in CLI search, and stop comparing a day's charge to fee times hours. Co-authored-by: Cursor --- api-reference/openapi.yaml | 7 ++++--- api-reference/openapi/yaml/show_earnings.yaml | 2 +- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 10 +++++++--- guides/instances/choosing/sla-coverage.mdx | 15 +++++++++------ host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 10 +++++----- host/upgrade-docker-and-packages.mdx | 7 ++++--- 8 files changed, 32 insertions(+), 23 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 92474cb1..c9fbf034 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -8064,9 +8064,10 @@ paths: type: number total_sla: type: number - description: Sum of sla_earn for the window (from per_day - when present, otherwise per_machine). Escrow released to - the host, not fees minus credits. + description: Sum of per_machine sla_earn when those rows are + present, otherwise the per_day sla_earn values. Escrow released + to the host, not fees minus credits. With a machine id this + total is that machine, while per_day stays fleet-wide. username: type: string email: diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 07923226..55b81fd7 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -71,7 +71,7 @@ paths: type: number total_sla: type: number - description: Sum of sla_earn for the window (from per_day when present, otherwise per_machine). Escrow released to the host, not fees minus credits. + description: Sum of per_machine sla_earn when those rows are present, otherwise the per_day sla_earn values. Escrow released to the host, not fees minus credits. With a machine id this total is that machine, while per_day stays fleet-wide. username: type: string email: diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 4daffadd..215b9fcd 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -131,7 +131,7 @@ curl -G "https://console.vast.ai/api/v0/charges/" \ ``` -Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). A negative amount, or one smaller than your SLA fee per hour times the hours the contract existed that day, can mean a credit was applied. The first and last days of a rental are partial. On a day with a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. See [Billing reconciliation](/guides/instances/choosing/sla-coverage#billing-reconciliation). The contract row can appear before settlement. Its `sla` item is absent until that day settles. If `next_token` is not `null`, repeat the request with `after_token` before you treat a missing `sla` item as unsettled. +Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). A negative `amount` is a net service credit. A positive `amount` is a net SLA fee. Do not expect that amount to equal the hourly SLA fee times hours. On a day with a Stop, a reboot, or a long Loading period, contact support before you treat the row as a credit. See [Billing reconciliation](/guides/instances/choosing/sla-coverage#billing-reconciliation). The contract row can appear before settlement. Its `sla` item is absent until that day settles. If `next_token` is not `null`, repeat the request with `after_token` before you treat a missing `sla` item as unsettled. diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 4e81f8f0..1aa76ff7 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -83,13 +83,17 @@ The CLI can find SLA offers but cannot price them. Treat `dph_total` as SLA-incl # neither the CLI nor the server filters on rented; drop .rented == true yourself if you need to vastai search offers 'reliability > 0.98 num_gpus=1 gpu_name=RTX_3090' --raw | jq '[.[] | select(.rented != true)]' -# Find SLA offers. dph_total here excludes the SLA fee (see the Warning below). +# Find SLA offers, then keep commitments of at least 99% in jq. +# Do not put has_sla and expected_reliability in one CLI query: the CLI sends +# the number as text and that pair fails on the server. +# dph_total here excludes the SLA fee (see the Warning below). # Always set --storage explicitly when comparing dph_total (CLI default 5 GiB ≠ REST 8 GB). -vastai search offers 'has_sla=true expected_reliability>=0.99' --storage 50 --order dph_total +vastai search offers 'has_sla=true' --storage 50 --order dph_total --raw \ + | jq '[.[] | select((.expected_reliability // 0) >= 0.99)]' ``` -The CLI can find SLA offers (`has_sla`, `expected_reliability`) but cannot price them. `vastai search offers 'target_reliability=0.95'` is sent as `{"eq": 0.95}` and fails with HTTP 400 (`target_reliability: Input should be a valid number`). Treat `dph_total` as SLA-inclusive only when the search set `target_reliability` in the console or REST. From the CLI, `--order dph_total` sorts by price without the SLA fee. +The CLI can find SLA offers with `has_sla=true`. Filter `expected_reliability` in `jq`, not in the same query string. The CLI cannot price an SLA. `vastai search offers 'target_reliability=0.95'` is sent as `{"eq": 0.95}` and fails with HTTP 400 (`target_reliability: Input should be a valid number`). Treat `dph_total` as SLA-inclusive only when the search set `target_reliability` in the console or REST. From the CLI, `--order dph_total` sorts by price without the SLA fee. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 67172dd0..2d348e64 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -38,7 +38,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. Write down **SLA Fee/hr**. You need it later to check credits, and the line is hidden while the instance is loading, stopped, or offline. Then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. -6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check credits in **Account → Billing → Charges** (not Invoices). Expand the instance row. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row closer to zero than your SLA Fee/hr times the hours the contract existed that UTC day. The first and last days of a rental are partial, so a row closer to zero on those days is not by itself a credit. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. +6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check **Account → Billing → Charges** (not Invoices). Expand the instance row. A **Service Credit** row (`+$`) means you were credited. An **SLA Fee** row (`−$`) is the fee. Do not compare that row to SLA Fee/hr times hours: the day's charge is not that product. If the row looks wrong, contact support with the contract ID and the UTC date. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -148,13 +148,14 @@ Console controls use the same concepts; they do not accept CLI query strings. Us **CLI examples:** -The current CLI cannot quote an SLA fee: it sends `target_reliability=0.95` as `{"eq": 0.95}`, which search rejects with `400 target_reliability: Input should be a valid number`. Use the CLI to find SLA offers (`has_sla`, `expected_reliability`), then get the SLA-inclusive `dph_total` from the console or REST (`"target_reliability": 0.95` as a plain number). +The current CLI cannot quote an SLA fee: it sends `target_reliability=0.95` as `{"eq": 0.95}`, which search rejects with `400 target_reliability: Input should be a valid number`. Use `has_sla=true` to find SLA offers, then filter `expected_reliability` with `jq`. Do not combine `has_sla=true` and `expected_reliability>=…` in one CLI query: the CLI sends that number as text and the server errors on the pair. Get the SLA-inclusive `dph_total` from the console or REST (`"target_reliability": 0.95` as a plain number). ```bash -# SLA offers where the host's reliability commitment is at least 99% +# SLA offers, then keep host commitments of at least 99%. # Set --storage to match the disk you will rent (console often 10; REST often 8+) -vastai search offers 'has_sla=true expected_reliability>=0.99' --storage 10 +vastai search offers 'has_sla=true' --storage 10 --raw \ + | jq '[.[] | select((.expected_reliability // 0) >= 0.99)]' ``` When you set `target_reliability`, search results include: @@ -293,12 +294,14 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta **4. Tear down.** Destroy the instance to end compute, storage, and SLA fee charges. On an SLA rental, see [Stop vs destroy](#what-you-pay-during-an-outage). Use [Delete Instance](/api-reference/instances/destroy-instance) or `vastai destroy instance NEW_CONTRACT`. Destroying deletes the instance disk. The `instance_write` permission covers this call. + + **Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Store the hourly SLA fee when the rent succeeds: `search.slaPremiumPerHour` on the `GET /api/v1/instances/` row for that contract. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. 1. Call Show Charges for one UTC day. `day.gte` and `day.lte` are both required (unix seconds). Set `day.lte` to `day.gte + 86399`. 2. Page with `after_token` / `next_token` until `next_token` is `null`. Space calls about one second apart. 3. Find the row whose `source` is `instance-` plus the contract id from `new_contract`, then the `items[]` entry with `type: "sla"`. -4. Compare that amount with the stored hourly fee times every hour the contract existed that UTC day, including downtime. The SLA fee keeps billing during outages, so do not count only running hours. A smaller or negative amount usually means a credit was applied. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. How the console labels the row is in [Settlement timing](#settlement-timing). +4. Read the sign of that `amount`. Positive is a net SLA fee. Negative is a net service credit. Do not expect the amount to equal `slaPremiumPerHour` times the hours the contract existed. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the row as a credit. How the console labels the row is in [Settlement timing](#settlement-timing). The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. If `next_token` is not `null`, repeat the request with `after_token` set to that value before you treat a missing `sla` item as unsettled. `limit` defaults to 100, so a busy account can put the contract on a later page. @@ -489,7 +492,7 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing → Charges**. **Service Credit** is a positive amount (`+$`). **SLA Fee** is a negative amount (`−$`). A partial credit is an **SLA Fee** row closer to zero than your SLA Fee/hr times the hours the contract existed that UTC day. The first and last days are partial, so a row closer to zero on those days is not by itself a credit. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the difference as a credit. The Charges API returns the same row with the opposite sign. Invoices do not. You cannot see the measured reliability for that day in the console or the API. +**Console:** After UTC settlement, open **Account → Billing → Charges**. A **Service Credit** row (`+$`) means you were credited. An **SLA Fee** row (`−$`) is the fee. Do not compare that row to SLA Fee/hr times hours. The Charges API returns the same row with the opposite sign: a negative `amount` is a net credit. Invoices do not show these rows. You cannot see the measured reliability for that day in the console or the API. **API integrators:** Use the same Charges row as [Settlement timing](#settlement-timing). The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. A row below the fee you expected means a credit was applied. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 00a65c2a..562e63e3 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -65,7 +65,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 1. Open **Account → API Keys** in the console and create a key with **`machine_read`** enabled. 2. Use `Authorization: Bearer YOUR_API_KEY` in the examples below. See [Create API Key](/api-reference/accounts/create-api-key) and [Authentication](/api-reference/authentication). -3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). New or idle machines should use the console **Set Pricing → SLA** preview instead (the backtester returns `has_data: false` without rental history). +3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). With no rental history the backtester returns `has_data: false`. Start **Confidence** at **Low** and confirm the fee in search. Do not wait on a console preview if **Set Pricing** has no **SLA** section. 4. Run the baseline request in [Example request](#example-request) and check `has_data` in the response. ## API reference diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1e08ad3f..1ab6ae33 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -48,7 +48,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Confirm an **SLA Fee** line. If that line is missing on every offer, SLA may be off platform-wide. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. - - **API users:** search with `verified=any` and confirm `expected_reliability` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true expected_reliability>=0.99' --storage 10`). The CLI may print `Warning: Unrecognized field` for `has_sla` and `expected_reliability`. That warning is harmless: the filter is still sent. On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). + - **API users:** search with `verified=any` and `has_sla=true` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw`). Confirm `expected_reliability` in `jq`. Do not add `expected_reliability>=…` to that CLI query: the CLI sends the number as text, and combining it with `has_sla=true` errors on the server. The CLI may print `Warning: Unrecognized field` for `has_sla`. That warning is harmless: the filter is still sent. On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). ## Before you enable SLA @@ -79,7 +79,7 @@ On an outage day the renter is still charged the normal hourly rate, and you may - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. -- **New or low-history machines:** If the backtester returns `has_data: false`, rely on the web console SLA preview. Wait for rental history before trusting backtester results. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. +- **New or low-history machines:** If the backtester returns `has_data: false`, there is no history to replay. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. Confirm the SLA fee renters see in search before you rely on a console preview. The **SLA** section under **Set Pricing** is not shown on every account. ## SLA in plain language @@ -276,7 +276,7 @@ In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIS #### Web console SLA preview -In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**. The preview shows estimated SLA fee and service-credit exposure for the parameters you enter. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) for history-based simulation. +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**, if that section is shown on your account. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) when you have rental history. If you do not see **SLA**, set the commitment with the API and confirm the fee renters see in search. ### API (for automation) @@ -777,7 +777,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ -d '{"sdate": START_UNIX_UTC, "duration": 2, "maintenance_category": "software"}' ``` -`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. There is no public REST endpoint for reading maintenance windows. Even if you schedule or cancel over REST, confirm the result with `vastai show maints --ids 'MACHINE_ID' --raw` or on the console **Maintenance** tab. Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. Retries must not create a duplicate of the same one. See [Schedule Maintenance](/api-reference/machines/schedule-maint). +`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. There is no public REST endpoint for reading maintenance windows. Even if you schedule or cancel over REST, confirm the result with `vastai show maints --ids 'MACHINE_ID' --raw`, or in the console under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. Retries must not create a duplicate of the same one. See [Schedule Maintenance](/api-reference/machines/schedule-maint). **Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. In scripts, pass `--retry 1` on `schedule maint` and `cancel maint`. A retried PUT can create a second window if the first one was stored and the response was lost. Confirm exactly one window before you schedule the next machine. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. In the console, **✕** on a row cancels that one window. With the CLI or REST, `cancel maint` removes every window on the machine. To change one window from the CLI, cancel all of them, then create again each window you still want. A new window starts its notice clock over. Confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). @@ -851,7 +851,7 @@ After you enable SLA, charges and credits settle on UTC (Coordinated Universal T - The backtester under-counts days that already had SLA rentals, so it cannot confirm a past credit. See [Simulation limits](/host/sla-backtester#simulation-limits). - SLA-contract compute is not included in `gpu_earn`, `sto_earn`, or bandwidth earnings. `sla_earn` is negative only when a prior day is corrected. - `per_day[].sla_earn` is fleet-wide even when you pass a machine ID. Use `per_machine[].sla_earn` for one machine. -- `summary.total_sla` adds up `sla_earn` for the window (from `per_day` when that list is present, otherwise from `per_machine`). Like `sla_earn`, it is escrow released to you, not fees minus credits. +- `summary.total_sla` is the sum of `per_machine[].sla_earn` when those rows are present, and uses `per_day` only when they are not. With a machine id, `total_sla` is that machine. `per_day[].sla_earn` stays fleet-wide. Like `sla_earn`, this is escrow released to you, not fees minus credits. ### Console (fleet totals only) diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index b5b805c4..d06bc76d 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -6,7 +6,7 @@ description: "Safely upgrade Docker, containerd, the NVIDIA stack, and other sys -If the machine has any rental, running or stopped, [schedule a maintenance window](/host/set-maintenance-window) before you start, as far ahead as you can. 48 hours is a courtesy, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. If nothing is rented, go to step 1. +If the machine has any rental, running or stopped, [schedule a maintenance window](/host/set-maintenance-window) before you start, as far ahead as you can. A 48-hour lead is a courtesy to renters, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. If nothing is rented, go to step 1. You are responsible for the maintenance and any resulting interruption. @@ -427,8 +427,7 @@ cat /etc/docker/daemon.json The `runtimes.nvidia.path` must still point at `kaalia_docker_shim`. Do not run `nvidia-ctk runtime configure` on a Vast machine: it replaces that path with -NVIDIA's default runtime and client instances stop working. If the file differs -from the above, restore it to this content and `sudo systemctl restart docker`. +NVIDIA's default runtime and client instances stop working. Check that `runtimes.nvidia` still has its `path` and that your `registry-mirrors` are still there. Keep any other keys the installer wrote, including `"exec-opts": ["native.cgroupdriver=cgroupfs"]` and `"live-restore": true`. Removing `live-restore` means a Docker restart stops every running container. Do not replace the whole file with the sample above. ### Images and containers @@ -496,6 +495,8 @@ restarting or the console stays Offline after 5 minutes, follow the ### Self-test +`vastai self-test machine` searches for a live offer first. If the machine is still unlisted it fails with no valid offers. Relist in the next section, then run: + ```bash vastai self-test machine ``` From b43968457fab2bfd8ae42db2264ee1e602c44f33 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 05:47:59 -0700 Subject: [PATCH 228/250] docs(sla): address doc-review consensus (cycle 172) Describe the Charges SLA row as one net amount, and stop the upgrade self-test from relisting before holds are back. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 10 +++++----- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 12 ++++++------ host/upgrade-docker-and-packages.mdx | 4 ++-- snippets/host/cli/show-maints.mdx | 6 ++++++ 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 215b9fcd..fda0a64e 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -131,7 +131,7 @@ curl -G "https://console.vast.ai/api/v0/charges/" \ ``` -Each `items[]` entry is the total for the whole query window, so this example is one UTC day (`day.lte` = `day.gte` + 86399). A negative `amount` is a net service credit. A positive `amount` is a net SLA fee. Do not expect that amount to equal the hourly SLA fee times hours. On a day with a Stop, a reboot, or a long Loading period, contact support before you treat the row as a credit. See [Billing reconciliation](/guides/instances/choosing/sla-coverage#billing-reconciliation). The contract row can appear before settlement. Its `sla` item is absent until that day settles. If `next_token` is not `null`, repeat the request with `after_token` before you treat a missing `sla` item as unsettled. +Each `items[]` entry is one net `type: "sla"` amount for the whole query window (fee minus any credit), so this example is one UTC day (`day.lte` = `day.gte` + 86399). Negative is a net credit. Positive is a net fee and can still include a partial credit. No field separates the two. See [Billing reconciliation](/guides/instances/choosing/sla-coverage#billing-reconciliation). The contract row can appear before settlement. Its `sla` item is absent until that day settles. If `next_token` is not `null`, repeat the request with `after_token` before you treat a missing `sla` item as unsettled. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 2d348e64..94520ba4 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -36,9 +36,9 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. 2. In **Search filters** (left bar), set **Reliability target**. If that control is missing, SLA is not available in the console right now. Rent without it, or contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai. 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. -4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. Write down **SLA Fee/hr**. You need it later to check credits, and the line is hidden while the instance is loading, stopped, or offline. Then click **RENT**. +4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. That line means the offer has an SLA. You cannot use **SLA Fee/hr** to calculate a credit. The line is hidden while the instance is loading, stopped, or offline. Then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. -6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), check **Account → Billing → Charges** (not Invoices). Expand the instance row. A **Service Credit** row (`+$`) means you were credited. An **SLA Fee** row (`−$`) is the fee. Do not compare that row to SLA Fee/hr times hours: the day's charge is not that product. If the row looks wrong, contact support with the contract ID and the UTC date. +6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), open **Account → Billing → Charges** (not Invoices). Each UTC day has one net SLA row: the fee minus any service credit. If the credit is larger than the fee, the row is **Service Credit** (`+$`). Otherwise it is **SLA Fee** (`−$`), and that row can still include a partial credit. You cannot see measured reliability, and you cannot split the fee from the credit. If a day had an outage and you need to know whether a credit was applied, contact support with the instance ID and the UTC date. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. @@ -301,7 +301,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta 1. Call Show Charges for one UTC day. `day.gte` and `day.lte` are both required (unix seconds). Set `day.lte` to `day.gte + 86399`. 2. Page with `after_token` / `next_token` until `next_token` is `null`. Space calls about one second apart. 3. Find the row whose `source` is `instance-` plus the contract id from `new_contract`, then the `items[]` entry with `type: "sla"`. -4. Read the sign of that `amount`. Positive is a net SLA fee. Negative is a net service credit. Do not expect the amount to equal `slaPremiumPerHour` times the hours the contract existed. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the row as a credit. How the console labels the row is in [Settlement timing](#settlement-timing). +4. Read the sign of that `amount`. Positive is a net SLA fee. Negative is a net service credit. A positive amount can still include a partial credit. No field separates the fee from the credit. Do not expect the amount to equal `slaPremiumPerHour` times hours. On a day that includes a Stop, a reboot, or a long Loading period, contact support before you treat the row as a credit. How the console labels the row is in [Settlement timing](#settlement-timing). The contract row can appear before settlement. Its `sla` item is absent until that day settles, so a window that includes the current UTC day has no SLA item yet. If `next_token` is not `null`, repeat the request with `after_token` set to that value before you treat a missing `sla` item as unsettled. `limit` defaults to 100, so a busy account can put the contract on a later page. @@ -492,9 +492,9 @@ No. Verification is a platform quality signal (see [Machine Tiers](/guides/insta ### Where do I see historical SLA credits? -**Console:** After UTC settlement, open **Account → Billing → Charges**. A **Service Credit** row (`+$`) means you were credited. An **SLA Fee** row (`−$`) is the fee. Do not compare that row to SLA Fee/hr times hours. The Charges API returns the same row with the opposite sign: a negative `amount` is a net credit. Invoices do not show these rows. You cannot see the measured reliability for that day in the console or the API. +**Console:** After UTC settlement, open **Account → Billing → Charges**. Each UTC day has one net SLA row (fee minus any credit). **Service Credit** (`+$`) means the credit was larger than the fee. **SLA Fee** (`−$`) is the net fee, and it can still include a partial credit. You cannot calculate the credit from this row. Invoices do not show it. -**API integrators:** Use the same Charges row as [Settlement timing](#settlement-timing). The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. A row below the fee you expected means a credit was applied. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). +**API integrators:** The `type: "sla"` item is one net amount (fee minus credit) for the window. Positive is a net fee. Negative is a net credit. A positive amount can still include a partial credit. No field separates the two, so you cannot detect a partial credit from the row alone. If a day had an outage, contact support with the instance ID and the UTC date. The call requires `day.gte` and `day.lte` (unix seconds). Send `next_token` back as `after_token`, and stop when `next_token` is `null`. `GET /api/v1/invoices/` covers payment transactions, not SLA credits. Client webhooks for SLA credits are not available. Host-side settlement uses [machine earnings](/api-reference/billing/show-earnings) (`sla_earn`). ## Related documentation diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 562e63e3..e754281a 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -65,7 +65,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 1. Open **Account → API Keys** in the console and create a key with **`machine_read`** enabled. 2. Use `Authorization: Bearer YOUR_API_KEY` in the examples below. See [Create API Key](/api-reference/accounts/create-api-key) and [Authentication](/api-reference/authentication). -3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). With no rental history the backtester returns `has_data: false`. Start **Confidence** at **Low** and confirm the fee in search. Do not wait on a console preview if **Set Pricing** has no **SLA** section. +3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). With no rental history the backtester returns `has_data: false`. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. The API returns `sla_not_approved` when the host is not approved. A missing section is not a fee preview. 4. Run the baseline request in [Example request](#example-request) and check `has_data` in the response. ## API reference diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1ab6ae33..bed372da 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -41,13 +41,13 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave **Reliability Commitment** (the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. -4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If the panel is missing, contact support. +4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. The API returns `sla_not_approved` when the host is not approved. A missing section is not a fee preview. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Reliability Commitment** and **Confidence**. Prefer a few weeks of rentals, then a [backtester](/host/sla-backtester) run, before you enable SLA. If you enable it earlier, the commitment is a guess: start it below the uptime you expect, and start **Confidence** at **Low** (wide margin). In **Set Pricing → SLA**, the commitment field is a percent (it ends with `%`; type `99` for 99%). Check that the SLA fee preview matches that percent before you **Save**. Use the console SLA preview or the backtester, not the dashboard reliability score. Search hides your offer from renters whose target is above your commitment. The machine is already listed from step 2, so **Save** publishes SLA to live renters immediately. +7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Confirm an **SLA Fee** line. If that line is missing on every offer, SLA may be off platform-wide. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. + - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. Console search cannot look up your machine by id. The reliable check is the client-key CLI command below. - **API users:** search with `verified=any` and `has_sla=true` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw`). Confirm `expected_reliability` in `jq`. Do not add `expected_reliability>=…` to that CLI query: the CLI sends the number as text, and combining it with `has_sla=true` errors on the server. The CLI may print `Warning: Unrecognized field` for `has_sla`. That warning is harmless: the filter is still sent. On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). ## Before you enable SLA @@ -79,7 +79,7 @@ On an outage day the renter is still charged the normal hourly rate, and you may - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. -- **New or low-history machines:** If the backtester returns `has_data: false`, there is no history to replay. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. Confirm the SLA fee renters see in search before you rely on a console preview. The **SLA** section under **Set Pricing** is not shown on every account. +- **New or low-history machines:** If the backtester returns `has_data: false`, there is no history to replay. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. Confirm the SLA fee renters see in search. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. The API returns `sla_not_approved` when the host is not approved. A missing section is not a fee preview. ## SLA in plain language @@ -276,7 +276,7 @@ In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIS #### Web console SLA preview -In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA**, if that section is shown on your account. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) when you have rental history. If you do not see **SLA**, set the commitment with the API and confirm the fee renters see in search. +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA** when that section is shown. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) when you have rental history. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. The API returns `sla_not_approved` when the host is not approved. A missing section is not a fee preview. ### API (for automation) @@ -777,7 +777,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ -d '{"sdate": START_UNIX_UTC, "duration": 2, "maintenance_category": "software"}' ``` -`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. There is no public REST endpoint for reading maintenance windows. Even if you schedule or cancel over REST, confirm the result with `vastai show maints --ids 'MACHINE_ID' --raw`, or in the console under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. Retries must not create a duplicate of the same one. See [Schedule Maintenance](/api-reference/machines/schedule-maint). +`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. Confirm the window with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)) or in the console under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). `--raw` is a JSON list. Each object includes `machine_id`, `start_time`, `end_time`, `duration_hours`, and `maintenance_category`. Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. Retries must not create a duplicate of the same one. If the work runs past the window, do not use `cancel maint` to lengthen it: that removes every window on the machine, and a new window starts its notice clock over. Remove one window with the console **✕**. See [Schedule Maintenance](/api-reference/machines/schedule-maint). **Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. In scripts, pass `--retry 1` on `schedule maint` and `cancel maint`. A retried PUT can create a second window if the first one was stored and the response was lost. Confirm exactly one window before you schedule the next machine. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. In the console, **✕** on a row cancels that one window. With the CLI or REST, `cancel maint` removes every window on the machine. To change one window from the CLI, cancel all of them, then create again each window you still want. A new window starts its notice clock over. Confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index d06bc76d..bfac8c1d 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -6,7 +6,7 @@ description: "Safely upgrade Docker, containerd, the NVIDIA stack, and other sys -If the machine has any rental, running or stopped, [schedule a maintenance window](/host/set-maintenance-window) before you start, as far ahead as you can. A 48-hour lead is a courtesy to renters, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. If nothing is rented, go to step 1. +This upgrade runs only when the machine has no running or stored instances. A maintenance window notifies renters. It does not remove their instances, and it does not let you upgrade while anything is still rented. If a rental remains, [schedule a window](/host/set-maintenance-window) as far ahead as you can, stay listed, and wait until step 1 shows the machine is empty. A 48-hour lead is a courtesy to renters, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. You are responsible for the maintenance and any resulting interruption. @@ -495,7 +495,7 @@ restarting or the console stays Offline after 5 minutes, follow the ### Self-test -`vastai self-test machine` searches for a live offer first. If the machine is still unlisted it fails with no valid offers. Relist in the next section, then run: +`vastai self-test machine` searches for a live offer first. If the machine is still unlisted it fails with no valid offers. Complete **Re-lock**, then **Relist**, below, and come back to run this. Do not relist before the holds are back. ```bash vastai self-test machine diff --git a/snippets/host/cli/show-maints.mdx b/snippets/host/cli/show-maints.mdx index 844bef6d..d687eca4 100644 --- a/snippets/host/cli/show-maints.mdx +++ b/snippets/host/cli/show-maints.mdx @@ -25,6 +25,12 @@ vastai show maints --ids 'machine_id_1,machine_id_2' [OPTIONS] vastai show maints --ids '12345,12346' --raw ``` +`--raw` prints a JSON list, one object per window. Each object includes `machine_id`, `start_time` (Unix seconds, UTC), `end_time`, `duration_hours`, and `maintenance_category`. To count windows that start at one time: + +```bash +vastai show maints --ids '12345' --raw | jq --argjson s 1784851200 '[.[] | select(.start_time == $s)] | length' +``` + ## Global Options The following options are available for all commands: From 2560167b286d28e432d551f2bb641e9ee7ec77b4 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 05:55:51 -0700 Subject: [PATCH 229/250] docs(sla): address doc-review consensus (cycle 173) Re-check rentals before a live fleet re-list, and stop the quick start from treating a missing SLA Fee line as hidden. Co-authored-by: Cursor --- api-reference/openapi.yaml | 18 +++--- api-reference/openapi/yaml/list_machine.yaml | 4 +- .../openapi/yaml/show_instances.yaml | 12 ++-- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 64 +++++++++++++------ host/upgrade-docker-and-packages.mdx | 2 +- 8 files changed, 65 insertions(+), 41 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index c9fbf034..f3dd92cc 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -4681,7 +4681,9 @@ paths: type: array items: type: integer - description: IDs of updated contracts + description: IDs of active rental contracts whose end date + this request extended. The array length equals extended. + These are not offer IDs. example: success: true you_sent: @@ -4694,7 +4696,7 @@ paths: extended: 1 new_contracts: [] upd_contracts: - - 1 + - 2000001 '400': description: Bad Request content: @@ -8532,7 +8534,7 @@ paths: format: float description: Total $/hour including storage (and SLA charge when applicable). - example: 0.8021 + example: 0.8101 target_reliability: type: - number @@ -8621,9 +8623,9 @@ paths: gpuCostPerHour: 0.8 diskHour: 0.0021 slaPremiumPerHour: 0.008 - totalHour: 0.8021 + totalHour: 0.8101 discountTotalHour: 0 - discountedTotalPerHour: 0.8013 + discountedTotalPerHour: 0.8101 instance: type: object description: Price breakdown for instance-context costs @@ -8638,11 +8640,11 @@ paths: example: 0.008 example: gpuCostPerHour: 0.8 - diskHour: 0.0013 + diskHour: 0.0021 slaPremiumPerHour: 0.008 - totalHour: 0.8021 + totalHour: 0.8101 discountTotalHour: 0 - discountedTotalPerHour: 0.5034 + discountedTotalPerHour: 0.8101 storage_cost: type: number format: float diff --git a/api-reference/openapi/yaml/list_machine.yaml b/api-reference/openapi/yaml/list_machine.yaml index 650042f4..8303e093 100644 --- a/api-reference/openapi/yaml/list_machine.yaml +++ b/api-reference/openapi/yaml/list_machine.yaml @@ -148,7 +148,7 @@ paths: type: array items: type: integer - description: IDs of updated contracts + description: IDs of active rental contracts whose end date this request extended. The array length equals extended. These are not offer IDs. example: success: true you_sent: @@ -160,7 +160,7 @@ paths: user_id: 67890 extended: 1 new_contracts: [] - upd_contracts: [1] + upd_contracts: [2000001] '400': description: Bad Request content: diff --git a/api-reference/openapi/yaml/show_instances.yaml b/api-reference/openapi/yaml/show_instances.yaml index d421764a..02a50c57 100644 --- a/api-reference/openapi/yaml/show_instances.yaml +++ b/api-reference/openapi/yaml/show_instances.yaml @@ -334,7 +334,7 @@ paths: type: number format: float description: Total $/hour including storage (and SLA charge when applicable). - example: 0.8021 + example: 0.8101 target_reliability: type: number format: float @@ -413,9 +413,9 @@ paths: gpuCostPerHour: 0.8 diskHour: 0.0021 slaPremiumPerHour: 0.008 - totalHour: 0.8021 + totalHour: 0.8101 discountTotalHour: 0 - discountedTotalPerHour: 0.8013 + discountedTotalPerHour: 0.8101 instance: type: object description: Price breakdown for instance-context costs (may include slaPremiumPerHour while running). @@ -428,11 +428,11 @@ paths: example: 0.008 example: gpuCostPerHour: 0.8 - diskHour: 0.0013 + diskHour: 0.0021 slaPremiumPerHour: 0.008 - totalHour: 0.8021 + totalHour: 0.8101 discountTotalHour: 0 - discountedTotalPerHour: 0.5034 + discountedTotalPerHour: 0.8101 storage_cost: type: number format: float diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 354094a0..44443d18 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -56,7 +56,7 @@ All stats shown are the portion of the total machine rented. - DLPERF score: A custom deep learning performance score - Price: The GPU rental price plus the hourly cost of the storage allocated. Hover over the price for a breakdown and for the price of bandwidth. When you set a **Reliability target**, the breakdown on SLA listings also shows an **SLA Fee** line — see [SLA](/guides/instances/choosing/sla-coverage). - Max Duration: The maximum length of a rental contract on this machine -- Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host reliability commitment. On an SLA offer that commitment is **expected reliability** (not this score). Your **Reliability target** must be at or below it. +- Reliability Score: A measure of the machine's historical uptime and health. All machines start at 60%. This is **not** the host's reliability commitment. On an SLA offer, that commitment is **expected reliability**. Your **Reliability target** must be at or below the host's **expected reliability**, not this score. Search hides offers whose commitment is below your target. - Rental Option: RENT button - **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA Fee** line in the price breakdown. An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 94520ba4..c0a510d5 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -36,7 +36,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. 2. In **Search filters** (left bar), set **Reliability target**. If that control is missing, SLA is not available in the console right now. Rent without it, or contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai. 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. -4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. That line means the offer has an SLA. You cannot use **SLA Fee/hr** to calculate a credit. The line is hidden while the instance is loading, stopped, or offline. Then click **RENT**. +4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. That line means this offer will be rented with an SLA at your target when you click **RENT**. If an offer shows no **SLA Fee** line, renting it gives you no SLA. Then click **RENT**. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. 6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), open **Account → Billing → Charges** (not Invoices). Each UTC day has one net SLA row: the fee minus any service credit. If the credit is larger than the fee, the row is **Service Credit** (`+$`). Otherwise it is **SLA Fee** (`−$`), and that row can still include a partial credit. You cannot see measured reliability, and you cannot split the fee from the credit. If a day had an outage and you need to know whether a credit was applied, contact support with the instance ID and the UTC date. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index e754281a..4560a04b 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -65,7 +65,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 1. Open **Account → API Keys** in the console and create a key with **`machine_read`** enabled. 2. Use `Authorization: Bearer YOUR_API_KEY` in the examples below. See [Create API Key](/api-reference/accounts/create-api-key) and [Authentication](/api-reference/authentication). -3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). With no rental history the backtester returns `has_data: false`. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. The API returns `sla_not_approved` when the host is not approved. A missing section is not a fee preview. +3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). With no rental history the backtester returns `has_data: false`. If **Set Pricing** has no **SLA** section, contact support before you list with SLA. `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. This backtester does not return that error. 4. Run the baseline request in [Example request](#example-request) and check `has_data` in the response. ## API reference diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index bed372da..bae0e08b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -41,14 +41,12 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave **Reliability Commitment** (the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. -4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. The API returns `sla_not_approved` when the host is not approved. A missing section is not a fee preview. +4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. Listing (`PUT /api/v0/machines/create_asks/`) returns 403 `sla_not_approved` when the host is not approved. A missing section is not a fee preview. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). -8. **Verify now.** From the client account, include unverified machines in Search filters (the default hides them; new machines usually are unverified) and set **Reliability target** at or below your commitment. Confirm an **SLA Fee** line. If that line is missing on every offer, SLA may be off platform-wide. Contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). - - **Console verify:** confirm **Listed** on **Host → Machines** and reopen **Set Pricing → SLA**. Console search cannot look up your machine by id. The reliable check is the client-key CLI command below. - - **API users:** search with `verified=any` and `has_sla=true` (for example `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw`). Confirm `expected_reliability` in `jq`. Do not add `expected_reliability>=…` to that CLI query: the CLI sends the number as text, and combining it with `has_sla=true` errors on the server. The CLI may print `Warning: Unrecognized field` for `has_sla`. That warning is harmless: the filter is still sent. On sliced machines, filter on-demand rows with the jq example in [Search / client-visible fields](#search--client-visible-fields). +8. **Verify now.** From your separate client account, run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. An offer in the result means the SLA listing is live. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that CLI query. In the console, sign in as the client, include unverified machines, set **Reliability target** at or below your commitment, and confirm an **SLA Fee** line. Console search cannot look up a machine by id. If no offer shows an **SLA Fee** line, contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). ## Before you enable SLA @@ -79,7 +77,7 @@ On an outage day the renter is still charged the normal hourly rate, and you may - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. -- **New or low-history machines:** If the backtester returns `has_data: false`, there is no history to replay. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. Confirm the SLA fee renters see in search. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. The API returns `sla_not_approved` when the host is not approved. A missing section is not a fee preview. +- **New or low-history machines:** If the backtester returns `has_data: false`, there is no history to replay. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. Confirm the SLA fee renters see in search. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. Listing (`PUT /api/v0/machines/create_asks/`) returns 403 `sla_not_approved` when the host is not approved. A missing section is not a fee preview. ## SLA in plain language @@ -276,7 +274,7 @@ In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIS #### Web console SLA preview -In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA** when that section is shown. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) when you have rental history. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. The API returns `sla_not_approved` when the host is not approved. A missing section is not a fee preview. +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA** when that section is shown. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) when you have rental history. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. Listing (`PUT /api/v0/machines/create_asks/`) returns 403 `sla_not_approved` when the host is not approved. A missing section is not a fee preview. ### API (for automation) @@ -576,28 +574,52 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do if [ "$DRY_RUN" != "0" ]; then echo "dry-run machine_id=$id payload: $body"; continue fi - resp=$(curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ + fresh=$(vastai show machines --raw --api-key "$VAST_API_KEY" 2>"$BTERR") + machine=$(printf '%s' "$fresh" | jq -c --argjson mid "$id" '.machines[] | select((.id|tonumber) == $mid)') + if ! printf '%s' "$machine" | jq -e 'has("current_rentals_resident") and .current_rentals_resident == 0' >/dev/null; then + echo "skip $id: rented since the snapshot, or current_rentals_resident missing" >&2 + continue + fi + body=$(echo "$machine" | jq -c --argjson hidden "$hidden" --arg vol "$VOL_SIZE" --arg sigma "$SIGMA" \ + '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, + min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim, + hidden_listing: $hidden} + + (if $sigma == "" then {} else {sla_sigma_x: ($sigma|tonumber)} end) + + (if .listed_inet_up_cost == null then {} else {price_inetu: .listed_inet_up_cost} end) + + (if .listed_inet_down_cost == null then {} else {price_inetd: .listed_inet_down_cost} end) + + (if .credit_discount_max == null then {} else {credit_discount_max: .credit_discount_max} end) + + (if .duration == null then {end_date} else {duration: (.duration | floor)} end) + + (if $vol == "" then {} else {vol_size: ($vol|tonumber)} end)') + tmp=$(mktemp) + http=$(curl -s -o "$tmp" -w '%{http_code}' -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ -H "Authorization: Bearer $VAST_API_KEY" \ -H "Content-Type: application/json" \ -d "$body") - ok=$(echo "$resp" | jq -r '.success // empty') - if [ "$ok" = "true" ]; then - echo "machine_id=$id ok extended=$(echo "$resp" | jq -c '.results[0].upd_contracts // []')" - if echo "$resp" | jq -e '.results[0].new_contracts | length > 0' >/dev/null; then - echo "WARN machine_id=$id: re-list created a new ask; confirm bandwidth, credit_discount_max, price_min_bid, and confidence (a new ask defaults sla_sigma_x to 0.5)" >&2 - fi - else - if echo "$resp" | grep -q 'sla_disabled'; then - echo "SLA disabled platform-wide; stopping run." >&2 - exit 1 - fi - echo "machine_id=$id error: $(echo "$resp" | jq -c '{success, error: (.error // .results[0].error), msg: (.msg // .results[0].msg)}' 2>/dev/null || echo "$resp")" - fi + case "$http" in + 200) + if jq -e '.success == true' "$tmp" >/dev/null; then + echo "machine_id=$id ok extended=$(jq -c '.results[0].upd_contracts // []' "$tmp")" + if jq -e '.results[0].new_contracts | length > 0' "$tmp" >/dev/null; then + echo "WARN machine_id=$id: re-list created a new ask; confirm bandwidth, credit_discount_max, price_min_bid, and confidence (a new ask defaults sla_sigma_x to 0.5)" >&2 + fi + elif grep -q 'sla_disabled' "$tmp"; then + echo "SLA disabled platform-wide; stopping run." >&2 + rm -f "$tmp" + exit 1 + else + echo "machine_id=$id error: $(jq -c '{success, error: (.error // .results[0].error), msg: (.msg // .results[0].msg)}' "$tmp" 2>/dev/null || head -c 200 "$tmp")" >&2 + fi + ;; + 429) echo "machine=$id http=429 rate limited; back off and retry this machine" >&2 ;; + 402) echo "machine=$id http=402 machine offline; skipped" >&2 ;; + *) echo "machine=$id http=$http $(head -c 200 "$tmp")" >&2 ;; + esac + rm -f "$tmp" sleep 5 done ``` -Fetch the fleet once before the loop — do not call `show machines --raw` inside the loop. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `listed_gpu_cost` round-trips: send it back as `price_gpu` and the price does not change. `min_bid_price` is different. It is reported net of the platform fee and does not round-trip, so never resend it as `price_min_bid`. On an existing ask, omitting `price_min_bid` keeps the stored minimum. After an unlist, send the value you wrote down. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. A storage price of `0` also keeps the stored price. Omitting `price_disk` is different: it resets storage to $0.10. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once to build the work list. Before each live PUT, the loop re-reads `show machines` and skips the machine if `current_rentals_resident` is not `0`. A machine can be rented between the snapshot and its turn, and a PUT on a rented machine can extend that rental. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `listed_gpu_cost` round-trips: send it back as `price_gpu` and the price does not change. `min_bid_price` is different. It is reported net of the platform fee and does not round-trip, so never resend it as `price_min_bid`. On an existing ask, omitting `price_min_bid` keeps the stored minimum. After an unlist, send the value you wrote down. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. A storage price of `0` also keeps the stored price. Omitting `price_disk` is different: it resets storage to $0.10. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index bfac8c1d..5d932961 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -6,7 +6,7 @@ description: "Safely upgrade Docker, containerd, the NVIDIA stack, and other sys -This upgrade runs only when the machine has no running or stored instances. A maintenance window notifies renters. It does not remove their instances, and it does not let you upgrade while anything is still rented. If a rental remains, [schedule a window](/host/set-maintenance-window) as far ahead as you can, stay listed, and wait until step 1 shows the machine is empty. A 48-hour lead is a courtesy to renters, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. +This upgrade runs only when the machine has no running or stored instances. A maintenance window notifies renters. It does not remove their instances, and it does not stop new rentals. The machine is empty only after the latest rental end date on **Host → Machines** has passed, or after renters destroy their instances. Schedule the window after that date. To stop new rentals while you wait, write down every **Set Pricing** field and then unlist (see [Severe outage](/host/sla-offers#severe-outage)). If the window starts and instances are still on the machine, do not upgrade. A 48-hour lead is a courtesy to renters, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. You are responsible for the maintenance and any resulting interruption. From b24873f514530dd26e3b95c3ba6f61b7d09f77b6 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 06:04:22 -0700 Subject: [PATCH 230/250] docs(sla): address doc-review consensus (cycle 174) Stop the fleet re-list on HTTP 403 sla_disabled, and relist only after the Docker holds are back. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 4 +- host/hosting-overview.mdx | 14 ++++-- host/sla-backtester.mdx | 4 +- host/sla-offers.mdx | 15 +++++-- host/upgrade-docker-and-packages.mdx | 48 ++++++++++----------- 8 files changed, 52 insertions(+), 39 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index fda0a64e..7e89c7ec 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -100,7 +100,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do - Create a **dedicated** key for this workflow only. `misc` covers offer search **and** unrelated routes such as serverless endpoints and workergroups. Constraints cannot limit `misc` to search only today. Treat a `misc` key as a high-impact secret. Do not reuse a full-access key. - **Search:** `misc` (no search-only permission exists). Search automation is rate-limited—see [Rate Limits and Errors](/api-reference/rate-limits-and-errors) and [API automation](/guides/instances/choosing/sla-coverage#api-automation) before production search loops. - **Rent:** `instance_write` on `PUT /api/v0/asks/{id}/` with `target_reliability`. -- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances --raw` (that command already calls v1). Store `search.slaPremiumPerHour` from the instance row when the rent succeeds. `instance.slaPremiumPerHour` is a cross-check only while the instance is running. It reads `0` while loading, stopped, or offline. +- **Verify:** `instance_read` with `GET /api/v1/instances/` or `vastai show instances --raw` (that command already calls v1). Store `search.slaPremiumPerHour` from the search offer you rented. Use the instance row only as a cross-check. If that row omits it, keep the search value. `instance.slaPremiumPerHour` reads `0` while loading, stopped, or offline. - **Charges:** add `billing_read` only if you read `sla` fee rows on `GET /api/v0/charges/`. The minimum key above cannot call Charges. ```json diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 1aa76ff7..2b0d53e3 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -191,7 +191,7 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability`. The CLI cannot send it: a query string becomes `{"eq": …}` and returns HTTP 400, so CLI `--raw` output has no SLA fee. The Python SDK can, if you pass a dict such as `search_offers(query={"has_sla": {"eq": True}, "target_reliability": 0.95})`. A string query fails the same way as the CLI. `search_offers()` cannot rent with SLA. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. +**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability`. The CLI cannot send it: a query string becomes `{"eq": …}` and returns HTTP 400, so CLI `--raw` output has no SLA fee. The Python SDK can, if you pass a dict such as `search_offers(query={"has_sla": {"eq": True}, "target_reliability": 0.95}, storage=50)`. Pass the same `storage` you will rent. The SDK default is 5 GiB, which changes `dph_total`. The SDK returns only the offers list. `truncated` is visible only via REST. A string query fails the same way as the CLI. `search_offers()` cannot rent with SLA. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. | Field | Meaning | | --- | --- | diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 44443d18..8a01f3b5 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -112,7 +112,7 @@ If you get this error when clicking the RENT button, the specific machine/GPU sl Startup time depends on the template and is usually under 5 minutes. If waiting over 20 minutes: - Ensure you're using a recommended template - Try a different machine -- Note: On a rental without an SLA, you're not charged while the instance is loading. On an SLA rental, see [what you pay during an outage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +- Note: On a rental without an SLA, you're not charged while the instance is loading. On an SLA rental, budget as if Loading time is charged. If you do not want to keep waiting, **Destroy** the instance and rent a different offer. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - With slow internet and large images, downloads can take an hour or more If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy**. Destroy ends the rental and permanently deletes the instance and its disk, so copy off anything you need first. If you rented with an SLA, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index c0a510d5..4a5e5265 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -296,7 +296,7 @@ Replace `NEW_CONTRACT` with the id from the rent response. Confirm top-level `ta -**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Store the hourly SLA fee when the rent succeeds: `search.slaPremiumPerHour` on the `GET /api/v1/instances/` row for that contract. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. +**Billing reconciliation:** Verifying the SLA on an instance does not show settlement. Store `search.slaPremiumPerHour` from the search offer you rented. Use the same field on the `GET /api/v1/instances/` row only as a cross-check. If that row omits it, keep the value from search. `instance.slaPremiumPerHour` reads `0` until the instance is running, and also while it is stopped or offline, so do not use it as the stored rate. 1. Call Show Charges for one UTC day. `day.gte` and `day.lte` are both required (unix seconds). Set `day.lte` to `day.gte + 86399`. 2. Page with `after_token` / `next_token` until `next_token` is `null`. Space calls about one second apart. @@ -355,7 +355,7 @@ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** be When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target and the host's reliability commitment are fixed for that rental. The host's pricing margin is also fixed, and it is not shown to you. When comparing offers, use the SLA fee line or `dph_total`. +1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and the rental end date are fixed for that rental. The host's pricing margin is also fixed, and it is not shown to you. When comparing offers, use the SLA fee line or `dph_total`. An SLA does not extend **Max Duration**. Reaching that end date is not an outage, so no credit is owed for the expiry itself. The host may extend the rental on the same terms. 2. **Charges and settlement** — compute, storage, and the SLA fee accrue while the rental contract is active, **including while the machine is offline**. That is different from a non-SLA rental. The net SLA row (SLA fee minus any service credit) settles once per UTC day. See [Settlement timing](#settlement-timing) and [What you pay during an outage](#what-you-pay-during-an-outage). 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA fee with no credit. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 6ec51131..2782d1f1 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -82,7 +82,7 @@ You can set the offer end date in the hosting interface by clicking on the date #### How the offer becomes a rental contract -When a client rents an instance from your offer, all of the offer's terms at that moment, the offer end date, the pricing, and the hardware specs, are locked into a **rental contract**. The offer end date becomes the contract's **rental end date** (shown in the UI as "client end date"), and the pricing becomes the contract's rate. Once created, price and SLA terms stay locked. Unlisting or editing the offer does not change them. **One exception:** sending an offer end date, at the same or lower price, extends every active rental that ends before that date. See [Extending rental contracts](#extending-rental-contracts). +When a client rents an instance from your offer, all of the offer's terms at that moment (the offer end date, the pricing, and the hardware specs) are locked into a **rental contract**. The offer end date becomes the contract's **rental end date** (shown in the UI as "client end date"), and the pricing becomes the contract's rate. Once created, price and SLA terms stay locked. Unlisting or editing the offer does not change them. **One exception:** sending an offer end date, at the same or lower price, extends every active rental that ends before that date. See [Extending rental contracts](#extending-rental-contracts). #### Can I change the offer? @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (**Reliability Commitment**, or **Confidence**, which is the fee margin) that would raise a contract's SLA fee means that contract is **not extended** by that request. A contract's SLA terms are locked when it is rented and never change. A contract skipped only for that fee change is extended by a later request only if your settings at that time no longer raise its SLA fee. Unlike a price increase, nothing is recorded that keeps blocking it. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (**Reliability Commitment**, or **Confidence**, which is the fee margin) that would raise a contract's SLA fee means that contract is **not extended** by that request. A contract's SLA terms are locked when it is rented and never change. A contract skipped only for that fee change is extended by a later request only if your settings at that time no longer raise its SLA fee. A price increase records a pending block that stops later extensions. A skip caused only by an SLA-fee change records nothing, so a later request can still extend the contract. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. @@ -203,13 +203,19 @@ It is vital to test your own machine to ensure the ports and software are runnin ### Set up a separate client account -There are two supported ways to test your own machine. If you want to use the website GUI, you will need to set up a new account on a different email address, add a credit card and then find your machine and create instances on it like a client. Include unverified machines in Search filters. New machines are usually unverified and are hidden by default. This has the benefit of showing you the entire client experience. Testing the recommended PyTorch template is vital to ensure that SSH and Jupyter are working properly. +There are two supported ways to test your own machine. If you want to use the website GUI, you will need to set up a new account on a different email address, add a credit card and then find your machine and create instances on it like a client. Testing from a separate account shows you the entire client experience. Include unverified machines in Search filters: new machines are usually unverified and are hidden by default. Testing the recommended PyTorch template is vital to ensure that SSH and Jupyter are working properly. ### Use the CLI (preferred) The preferred method of testing your own machine is to run the [CLI](https://cloud.vast.ai/cli/). For Windows users, we suggest setting up [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) which will require you to install Ubuntu on your Windows machine and change your bios settings to allow virtualization. Then you can start an Ubuntu terminal and run the CLI. -To rent your own machine you will need to first search the offers with your machine ID to find the ID and then create an instance using that ID. Use the **host** account key for `show machines` and a separate **client** account key for `search offers` and `create instance` (`--api-key`). A host key can rent offers on your own machines. Every other offer returns HTTP 400 `invalid_args` (`error 403/3586`). Use the client key so the test matches a real renter. The show machine command will show all your connected machines. +To rent your own machine you will need to first search the offers with your machine ID to find the ID and then create an instance using that ID. Sign in to the separate client account, open **Account → API Keys**, and [create a key](/api-reference/accounts/create-api-key). Then set it in your shell: + +```bash +export CLIENT_API_KEY='key from the client account' +``` + +Use the **host** account key for `show machines` and `$CLIENT_API_KEY` for `search offers` and `create instance`. A host key can rent offers on your own machines. Every other offer returns HTTP 400 `invalid_args` (`error 403/3586`). Use the client key so the test matches a real renter. The show machine command will show all your connected machines. ```text Text ./vastai show machines diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 4560a04b..4e0e08af 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -65,7 +65,7 @@ For how SLA offers work once listed, see [SLA Offers](/host/sla-offers). 1. Open **Account → API Keys** in the console and create a key with **`machine_read`** enabled. 2. Use `Authorization: Bearer YOUR_API_KEY` in the examples below. See [Create API Key](/api-reference/accounts/create-api-key) and [Authentication](/api-reference/authentication). -3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). With no rental history the backtester returns `has_data: false`. If **Set Pricing** has no **SLA** section, contact support before you list with SLA. `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. This backtester does not return that error. +3. Find your machine ID on the [Host Machines page](https://cloud.vast.ai/host/machines). With no rental history the backtester returns `has_data: false`. If **Set Pricing** has no **SLA** section, see [checklist step 4](/host/sla-offers#sla-host-checklist). This backtester does not return `sla_not_approved`. That error comes from listing. 4. Run the baseline request in [Example request](#example-request) and check `has_data` in the response. ## API reference @@ -281,7 +281,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** ## Fleet workflow -Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. For machines that already have SLA enabled, the replay under-counts those days. Treat `largest_day_credit` as a lower bound. `net_sla` can be off in either direction, because both fees and credits are understated. For a cleaner estimate, set `START` and `END` (Unix seconds) to a window from before SLA was enabled, and set `T` to the renter target you want to model (for example `0.95`, and not above the commitment you send). See [Simulation limits](#simulation-limits). +Optional, for API automation only. To check one machine, use the single-machine request above. `vastai show machines --raw` leaves out machines offline for more than about 10 hours. To include them (up to about 3 days), list machines with `GET /api/v0/machines/?include_offline=true`. For machines that already have SLA enabled, the replay under-counts days that already had SLA rentals. Treat `largest_day_credit` as a lower bound. `net_sla` can be off in either direction, because both fees and credits are understated. For a cleaner estimate, set `START` and `END` (Unix seconds) to a window from before SLA was enabled, and set `T` to the renter target you want to model (for example `0.95`, and not above the commitment you send). See [Simulation limits](#simulation-limits). **Prerequisites:** [CLI hello world](/cli/hello-world) and an API key with `machine_read` (see [API permissions](/api-reference/permissions)). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index bae0e08b..6964732f 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -46,7 +46,8 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). -8. **Verify now.** From your separate client account, run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. An offer in the result means the SLA listing is live. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that CLI query. In the console, sign in as the client, include unverified machines, set **Reliability target** at or below your commitment, and confirm an **SLA Fee** line. Console search cannot look up a machine by id. If no offer shows an **SLA Fee** line, contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. See [Testing your own machine](/host/hosting-overview#testing-your-own-machine). +8. **Verify now.** In the console, sign in as your separate client account, include unverified machines, set **Reliability target** at or below your commitment, and confirm an **SLA Fee** line. Console search cannot look up a machine by id. If no offer shows that line, contact support before you change the listing. + - **Optional (CLI):** create a client key first ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)), then run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Do not add `expected_reliability>=…` to that query. Confirm `expected_reliability` with `jq`. Optionally rent that offer briefly, then **Destroy** the test instance. ## Before you enable SLA @@ -77,7 +78,7 @@ On an outage day the renter is still charged the normal hourly rate, and you may - Optional: run the [backtester](/host/sla-backtester) after you have weeks of history; otherwise use the web console SLA preview and the economics walkthrough on this page. -- **New or low-history machines:** If the backtester returns `has_data: false`, there is no history to replay. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. Confirm the SLA fee renters see in search. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. Listing (`PUT /api/v0/machines/create_asks/`) returns 403 `sla_not_approved` when the host is not approved. A missing section is not a fee preview. +- **New or low-history machines:** If the backtester returns `has_data: false`, there is no history to replay. Start **Confidence** at **Low** (wider margin, larger fee) or use a more conservative reliability commitment until you have a few weeks of data. Confirm the SLA fee renters see in search. If **Set Pricing** has no **SLA** section, use [checklist step 4](#sla-host-checklist). ## SLA in plain language @@ -274,7 +275,7 @@ In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIS #### Web console SLA preview -In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA** when that section is shown. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) when you have rental history. If **Set Pricing** has no **SLA** section, contact support before you enable SLA. Listing (`PUT /api/v0/machines/create_asks/`) returns 403 `sla_not_approved` when the host is not approved. A missing section is not a fee preview. +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA** when that section is shown. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) when you have rental history. If **Set Pricing** has no **SLA** section, use [checklist step 4](#sla-host-checklist). ### API (for automation) @@ -611,6 +612,14 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do fi ;; 429) echo "machine=$id http=429 rate limited; back off and retry this machine" >&2 ;; + 403) + if grep -q sla_disabled "$tmp"; then + echo "SLA disabled platform-wide; stopping run." >&2 + rm -f "$tmp" + exit 1 + fi + echo "machine=$id http=403 $(head -c 300 "$tmp")" >&2 + ;; 402) echo "machine=$id http=402 machine offline; skipped" >&2 ;; *) echo "machine=$id http=$http $(head -c 200 "$tmp")" >&2 ;; esac diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index 5d932961..53e22129 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -67,7 +67,7 @@ Occ: 0 #Stored: D: 0, I: 0, R: 0 ``` -No `C.` lines and all three at 0 means the machine is free. If it has an SLA, write down every **Set Pricing** field first (GPU, storage, and bandwidth prices, minimum GPUs, end date, reserved discount, min bid, whether the listing is hidden, **Reliability Commitment**, and **Confidence**). Unlisting drops the SLA ask, and `show machines` will not return the exact confidence afterward. See [Severe outage](/host/sla-offers#severe-outage). Then unlist so nobody rents it while Docker or the GPUs are down, and continue at step 2: +No `C.` lines and all three at 0 means the machine is free. Before you unlist, write down every **Set Pricing** field (GPU, storage, and bandwidth prices, minimum GPUs, end date, reserved discount, min bid, and whether the listing is hidden). Relisting creates a new offer. Bandwidth can come back at $0, the reserved discount at 0.4, and a hidden listing can come back public. If the machine has an SLA, also write down **Reliability Commitment** and **Confidence**. Unlisting drops the SLA ask, and `show machines` will not return the exact confidence afterward. See [Severe outage](/host/sla-offers#severe-outage). Then unlist so nobody rents it while Docker or the GPUs are down, and continue at step 2: ```bash vastai unlist machine @@ -76,14 +76,12 @@ vastai unlist machine See [`vastai unlist machine`](/host/cli/unlist-machine). -**If anything is rented and you still want to upgrade:** stay listed and schedule a maintenance window instead of unlisting. A window does not stop new rentals. If you need to stop them, save the listing terms above, then unlist. On an SLA machine, see [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Do not stop or delete client containers. +If anything is rented, you cannot upgrade yet. A maintenance window does not remove renters' instances, and staying listed lets new rentals arrive. -```bash -vastai schedule maint MACHINE_ID --sdate UNIX_UTC --duration HOURS --maintenance_category software -``` - -See [`vastai schedule maint`](/host/cli/schedule-maint). When the window starts, -repeat both checks above and continue only when both are clear. +1. Write down every **Set Pricing** field, then unlist so no new rental pushes the end date later. +2. Wait until the latest rental end date on **Host → Machines** has passed, or until renters destroy their instances. +3. Schedule the maintenance window for after that date. +4. If the window starts and instances are still there, do not stop them. Reschedule the window instead. ## 2. Check what needs upgrading @@ -493,22 +491,6 @@ If `Loaded:` says `masked`, redo the start commands above. If the daemon keeps restarting or the console stays Offline after 5 minutes, follow the [Offline Machine](/host/machine-offline) page from its step 2. -### Self-test - -`vastai self-test machine` searches for a live offer first. If the machine is still unlisted it fails with no valid offers. Complete **Re-lock**, then **Relist**, below, and come back to run this. Do not relist before the holds are back. - -```bash -vastai self-test machine -``` - -```text nocopy -... -Test completed successfully. -``` - -The last line must be `Test completed successfully.`. On failure the output -names the failing check; see [How to self-test](/host/how-to-self-test). - ### Re-lock The daemon puts its holds back within the hour. Run its script now so the @@ -553,7 +535,7 @@ Canceled hold on linux-image-generic-hwe-24.04. ### Relist -Relist from the [Machines page](https://cloud.vast.ai/host/machines/). If the machine had an SLA, use **Set Pricing → SLA → Save → LIST** and re-enter every field you wrote down. `vastai list machine` creates the ask without SLA and can reset bandwidth and other fields. See the [`list machine` cautions](/host/cli/list-machine). After 2 to 3 +Relist from the [Machines page](https://cloud.vast.ai/host/machines/). Re-enter every **Set Pricing** field you wrote down. If the machine had an SLA, relist with **Reliability Commitment** at `0`, run the self-test below, and only then set your SLA terms and click **Save**. If the self-test fails, unlist right away. `vastai list machine` creates the ask without SLA and can reset bandwidth and other fields. See the [`list machine` cautions](/host/cli/list-machine). After 2 to 3 minutes: ```bash @@ -567,6 +549,22 @@ ID CUDA N Model PCIE cpu_ghz vCPUs RAM Disk $/hr DLP ... A result row means the machine is listed. +### Self-test + +`vastai self-test machine` searches for a live offer first. Run it only after **Re-lock** and **Relist**. + +```bash +vastai self-test machine +``` + +```text nocopy +... +Test completed successfully. +``` + +The last line must be `Test completed successfully.`. On failure the output +names the failing check; see [How to self-test](/host/how-to-self-test). If it fails and you already relisted an SLA machine, unlist it. + New Docker, containerd and driver; every GPU visible on the host and in a container; daemon running; self-test passed; daemon holds back; kernel hold From 438d2d239759cc875c6af46b177db530db2ba3f1 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 06:18:18 -0700 Subject: [PATCH 231/250] docs(sla): address doc-review consensus (cycle 175) An extension checks the SLA fee only when the request includes SLA fields. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 8 +++--- host/hosting-overview.mdx | 4 +-- host/sla-offers.mdx | 31 +++++++++++++++------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 4a5e5265..af171996 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -23,9 +23,9 @@ A few things people mix up: - The **reliability score** on an offer card is a separate marketplace signal. It is not your SLA. - The GPU bill does **not** stop during an outage. A credit is paid only when the blended measure falls below your target, usually after the next UTC midnight. A short outage that stays above the target is billed in full with no credit. -- Filtering for SLA offers (`has_sla`, SLA-enabled), or a CLI or API search, does **not** turn on an SLA. Setting **Reliability target** in the console Search filters and then clicking **RENT**, or sending `target_reliability` on REST rent, does. The CLI cannot turn SLA on. +- Filtering for SLA offers does not turn on an SLA. Set **Reliability target** in the Search filters before you click **RENT**. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. -- If the Search offer has **no SLA Fee line**, you do not have an SLA. On an instance, that line appears only while the instance is **running**. In **Account → Billing → Charges**, **Service Credit** is shown as a positive amount (`+$`) and **SLA Fee** as a negative amount (`−$`). The API `amount` has the opposite sign. In API responses the hourly amount is `slaPremiumPerHour`. +- If the Search offer has **no SLA Fee** line, renting it gives you no SLA. On an instance, that line appears only while the instance is **running**. For how SLA amounts appear in **Charges**, see [Settlement timing](#settlement-timing). Hosts who want the same idea from the listing side can read [SLA in plain language](/host/sla-offers#sla-in-plain-language). @@ -234,7 +234,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ The CLI default query is `external=false rentable=true verified=true`. Neither the CLI nor the server filters on `rented`. REST `POST /api/v0/bundles/` drops that key and still returns a `rented` flag on each offer. Drop rows where `rented` is true if you need to hide GPUs you already rent. The response includes `truncated`. When it is `true`, the server cut the result short of `limit`. Narrow the query instead of assuming you saw every offer. -Server-side sort by `dph_total` puts offers that could not be SLA-priced first, because they have no SLA fee. Drop them, then sort again. You may need a larger `limit` to make up for the dropped rows. +Server-side sort by `dph_total` can put a row with no SLA fee first. Offers whose SLA terms fail validation are left out of the results. They still count against `limit`, so a page can return fewer rows than you asked for. A row that comes back with `slaPremiumPerHour` of `0` while you set `target_reliability` has incomplete SLA terms. Drop it, then sort again. Do not rent it. ```bash curl ... | jq '.offers | map(select((.search.slaPremiumPerHour // 0) > 0)) | sort_by(.dph_total)' @@ -473,7 +473,7 @@ Host ask field `sla_r_claim` on listings is host-side; on active rentals the loc - **Interruptible (bid) rentals** never include SLA, even on SLA-enabled machines. Use on-demand with a reliability target set. - **Prepaid / reserved-only flows** may reject SLA parameters. Use on-demand rentals for an SLA. - Offers without SLA (`expected_reliability = 0` / `has_sla=false`) are excluded when you filter with `has_sla=true` or set a positive `target_reliability`. -- If SLA pricing fails for an offer, that row has no positive SLA fee (`search.slaPremiumPerHour` in the API) even though you set a target. Treat it as unpriced. Drop it before you sort by price, and do not rent it. +- Offers whose SLA terms fail validation are left out of search. A row with `slaPremiumPerHour` of `0` while you set a target has incomplete SLA terms. Drop it before you sort by price, and do not rent it. - If **every** row is missing `expected_reliability` and `search.slaPremiumPerHour` even though you sent `target_reliability`, SLA may be turned off platform-wide. Search does not return an error in that case. A rent that includes `target_reliability` then returns `403 sla_disabled`. Contact support. Do not treat an empty SLA filter as "no hosts offer SLA" until you have ruled this out. ## FAQ diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 2782d1f1..2fe49396 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -93,7 +93,7 @@ Yes, but changes only affect future rental contracts. Existing rental contracts - **Extending** the offer end date allows new clients to rent for a longer period. It also extends every active rental that ends sooner than the new date, including SLA rentals and their credit exposure. See [Extending rental contracts](#extending-rental-contracts). - **Unlisting** the machine prevents new rental contracts entirely, but existing ones continue at their original pricing and rental end dates -You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, a change to your SLA settings (**Reliability Commitment**, or **Confidence**, which is the fee margin) that would raise a contract's SLA fee means that contract is **not extended** by that request. A contract's SLA terms are locked when it is rented and never change. A contract skipped only for that fee change is extended by a later request only if your settings at that time no longer raise its SLA fee. A price increase records a pending block that stops later extensions. A skip caused only by an SLA-fee change records nothing, so a later request can still extend the contract. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). A machine can have active rentals at different prices and different end dates. +You can also unlist and relist with entirely new terms (new price, new offer end date). New rental contracts use the new terms. A relist at the same or lower price with a later end date extends shorter active rentals to that date. If you offer an SLA, read [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts) before you change SLA terms or move `end_date`. Some of those requests skip a contract, and some extend it with no SLA fee check. A machine can have active rentals at different prices and different end dates. The latest rental end date across all active rental contracts on a machine is shown in the UI. You must keep the machine available until this date. @@ -195,7 +195,7 @@ This will automatically remove expired/deleted rental contracts from the machine ## Extending Rental Contracts -Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. Lowering your **Reliability Commitment** or moving **Confidence** toward **Low** in that same request also skips any SLA contract whose fee would rise. A later request extends it only if your settings no longer raise its SLA fee. For SLA rentals, an extension also extends service-credit exposure. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). +Sending a later end date at the same or lower price extends active contracts that end sooner. Raising the GPU, disk, or bandwidth price does not extend them. For SLA rentals, an extension also extends service-credit exposure. The SLA fee check runs only when the request includes SLA fields. See [SLA on extended contracts](/host/sla-offers#sla-on-extended-contracts). ## Testing your own machine diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 6964732f..2f7733e6 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -38,11 +38,15 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong ## SLA host checklist +Read [SLA in plain language](#sla-in-plain-language) before this list. + 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave **Reliability Commitment** (the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. -4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. Listing (`PUT /api/v0/machines/create_asks/`) returns 403 `sla_not_approved` when the host is not approved. A missing section is not a fee preview. -5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. The normal **Host → Billing** view has no separate SLA earnings line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn` (`vastai show earnings`). Much of it can stay held until the contract ends, so a low week is not by itself a credit. +4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. + - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. +5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. + - **API users:** **Host → Billing** has no per-machine SLA line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn`. Much of it can stay held until the contract ends, so a low week is not by itself a credit. See [Monitoring SLA after listing](#monitoring-sla-after-listing). 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). @@ -236,10 +240,10 @@ On a listed machine, moving the offer end date later extends every shorter activ - **Extends shorter rentals:** a request that sends `end_date` or `duration` at the same or a lower GPU, disk, and bandwidth price. - **Skips that contract:** the request raises the GPU, disk, or bandwidth price. For some renters this records a pending price increase, and later extension requests also skip that contract until the renter accepts or declines it. A request that would raise the contract's SLA fee, or that fails an SLA check (for example `sla_r_claim: 0` or a reliability commitment below that contract's target), also skips it. The contract keeps its end date and is missing from `upd_contracts`. -- **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A skip caused only by an SLA-fee change does not record a lasting block. A later request extends that contract only if your settings no longer raise its SLA fee. A pending price increase does keep blocking later extensions. +- **Not the whole story:** `upd_contracts` can miss rentals extended a few minutes later. A skip caused only by an SLA-fee change does not record a lasting block. A later request that includes `sla_r_claim` or `sla_sigma_x` extends that contract only if those values no longer raise its SLA fee. A later request that omits both fields extends it with no fee check. A pending price increase does keep blocking later extensions. - **You cannot see each contract's end date in the documented API.** **Host → Machines** shows the latest rental end date on the machine. You cannot confirm in advance which rentals a later `end_date` will extend. -Changing the reliability commitment or Confidence does not change the SLA fee already locked on a contract. Only new rentals pick up the new terms. Extending a contract re-checks it against your current settings. If those settings would raise that renter's SLA fee, the contract is not extended and keeps its original end date. Hosts do not set the SLA fee. It changes when you change the reliability commitment or Confidence (a wider margin, console **Low**, raises the fee at a given target). +Changing the reliability commitment or Confidence does not change the SLA fee already locked on a contract. Only new rentals pick up the new terms. The SLA check on an extension runs only when that request includes `sla_r_claim` or `sla_sigma_x`. Vast then compares the values you sent with that contract's locked terms and skips the contract if the SLA fee would rise. A request that omits both fields, including `vastai list machine -e` or `-l` and a REST body without those fields, extends every shorter rental, including SLA contracts, with no fee check. Hosts do not set the SLA fee. It changes when you change the reliability commitment or Confidence (a wider margin, console **Low**, raises the fee at a given target). Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-covered contracts but does not terminate SLA on existing active contracts — they continue under their original SLA terms until their rental end date. @@ -315,7 +319,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ Replace `CURRENT_STORAGE_PRICE`, `CURRENT_INET_UP`, `CURRENT_INET_DOWN`, `CURRENT_DISCOUNT`, and `CURRENT_MIN_CHUNK` from `vastai show machines --raw` (`listed_storage_cost`, `listed_inet_up_cost`, `listed_inet_down_cost`, `credit_discount_max`, and `listed_min_gpu_count`). On an existing ask, omit `price_min_bid`. The stored minimum is kept. Do not copy `min_bid_price` into the body. That value is net of the platform fee, and resending it shifts the minimum on every update. After an unlist, send the `price_min_bid` you wrote down yourself. `show machines` does not report hidden status. Set `CURRENT_HIDDEN` from your own notes or **Set Pricing**. Sending `false` for a hidden listing makes it public. An unedited paste is not valid JSON. Include bandwidth and the discount in the body so a new ask does not publish at $0 bandwidth or the 0.4 discount default. If the response has `.results[0].new_contracts` with any entries, the PUT created a new ask. Confirm `price_inetu`, `price_inetd`, `credit_discount_max`, `price_min_bid`, and `sla_sigma_x` on that ask. A new ask resets omitted values to their defaults. Send `end_date` only in the full listing update below, when you mean to extend. -Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price, or changes the reliability commitment or Confidence in a way that would raise that contract's SLA fee. A reliability-commitment or Confidence change does not record a lasting block. A later request extends that contract only if your settings no longer raise its SLA fee (see [SLA on extended contracts](#sla-on-extended-contracts)). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). +Any active rental that ends **before** the `end_date` you send is extended to that date, unless the same request raises the GPU, disk, or bandwidth price. If that request also includes `sla_r_claim` or `sla_sigma_x`, a contract whose SLA fee would rise is skipped, and that skip does not record a lasting block. A request without those fields extends the rental with no fee check. See [SLA on extended contracts](#sla-on-extended-contracts). Resending the offer's current `end_date` is not a no-op when some rentals end sooner. `upd_contracts` lists only contracts extended immediately. See [Extending rental contracts](/host/hosting-overview#extending-rental-contracts). #### Full listing update (existing ask) @@ -577,10 +581,19 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do fi fresh=$(vastai show machines --raw --api-key "$VAST_API_KEY" 2>"$BTERR") machine=$(printf '%s' "$fresh" | jq -c --argjson mid "$id" '.machines[] | select((.id|tonumber) == $mid)') - if ! printf '%s' "$machine" | jq -e 'has("current_rentals_resident") and .current_rentals_resident == 0' >/dev/null; then - echo "skip $id: rented since the snapshot, or current_rentals_resident missing" >&2 + if ! printf '%s' "$machine" | jq -e '.listed == true and (.sla_reliability_claim // 0) > 0 and .sla_confidence != null and has("current_rentals_resident") and .current_rentals_resident == 0' >/dev/null; then + echo "skip $id: fresh read failed listing, SLA, or rental gate" >&2 continue fi + fresh_dur=$(printf '%s' "$machine" | jq -r '.duration // empty') + if [ -z "$fresh_dur" ]; then + fresh_end=$(printf '%s' "$machine" | jq -r '.end_date // empty') + fresh_now=$(date -u +%s) + if ! jq -e -n --argjson e "$fresh_end" --argjson n "$fresh_now" '$e > $n' >/dev/null 2>&1; then + echo "skip $id: end_date expired on fresh read" >&2 + continue + fi + fi body=$(echo "$machine" | jq -c --argjson hidden "$hidden" --arg vol "$VOL_SIZE" --arg sigma "$SIGMA" \ '{machine: (.id|tonumber), price_gpu: .listed_gpu_cost, price_disk: .listed_storage_cost, min_chunk: .listed_min_gpu_count, sla_r_claim: .sla_reliability_claim, @@ -628,7 +641,7 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do done ``` -Fetch the fleet once to build the work list. Before each live PUT, the loop re-reads `show machines` and skips the machine if `current_rentals_resident` is not `0`. A machine can be rented between the snapshot and its turn, and a PUT on a rented machine can extend that rental. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `listed_gpu_cost` round-trips: send it back as `price_gpu` and the price does not change. `min_bid_price` is different. It is reported net of the platform fee and does not round-trip, so never resend it as `price_min_bid`. On an existing ask, omitting `price_min_bid` keeps the stored minimum. After an unlist, send the value you wrote down. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. A storage price of `0` also keeps the stored price. Omitting `price_disk` is different: it resets storage to $0.10. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. +Fetch the fleet once to build the work list. Before each live PUT, the loop re-reads `show machines` and skips the machine unless it is still listed, still has a positive commitment and stored confidence, has `current_rentals_resident` of `0`, and, when `duration` is null, still has a future `end_date`. The loop sends listed bandwidth prices and `credit_discount_max` when `show machines` returns them (listed machines only; `null` after unlist). The loop does not send `price_min_bid`. `listed_gpu_cost` round-trips: send it back as `price_gpu` and the price does not change. `min_bid_price` is different. It is reported net of the platform fee and does not round-trip, so never resend it as `price_min_bid`. On an existing ask, omitting `price_min_bid` keeps the stored minimum. After an unlist, send the value you wrote down. On an existing ask, a bandwidth price of `0` is treated as omitted and the old price is kept. A storage price of `0` also keeps the stored price. Omitting `price_disk` is different: it resets storage to $0.10. On fleets of 20+ machines, expect several minutes; back off on HTTP 429. Configure reliability commitment and confidence per machine (console or single-machine `create_asks`) before running with `DRY_RUN=0` — the loop only updates machines that already have a positive `sla_r_claim`. @@ -839,7 +852,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep - **Severe outage (active SLA contracts):** **Console** - 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). + 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). Change **Maintenance start** to a few minutes from now. The form starts 24 hours ahead. An emergency window is still unplanned, so expect full SLA exposure for it. 2. Write down every field on **Set Pricing**: GPU price, minimum GPUs, storage price, bandwidth, reserved discount, min bid, whether the listing is **hidden**, the offer end date or auto-renew duration, **Reliability Commitment**, and **Confidence**. If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. From a8b03d31deb9937e93957ff116a13f4f1f2f364c Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 06:49:00 -0700 Subject: [PATCH 232/250] docs(sla): address doc-review consensus (cycle 176) The console cannot turn SLA off with 0, and every Save sends the listing end date. Co-authored-by: Cursor --- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 6 +++--- guides/reference/billing.mdx | 2 +- host/sla-offers.mdx | 17 ++++++++++------- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 8a01f3b5..bcfa519c 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -112,7 +112,7 @@ If you get this error when clicking the RENT button, the specific machine/GPU sl Startup time depends on the template and is usually under 5 minutes. If waiting over 20 minutes: - Ensure you're using a recommended template - Try a different machine -- Note: On a rental without an SLA, you're not charged while the instance is loading. On an SLA rental, budget as if Loading time is charged. If you do not want to keep waiting, **Destroy** the instance and rent a different offer. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +- Note: On a rental without an SLA, you are not charged for GPU time while the instance is **Loading**. Storage is still charged. On an SLA rental, budget as if Loading time is charged. If you do not want to keep waiting, **Destroy** the instance and rent a different offer. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). - With slow internet and large images, downloads can take an hour or more If the instance never becomes healthy, open **Instances**, select the rental, and choose **Destroy**. Destroy ends the rental and permanently deletes the instance and its disk, so copy off anything you need first. If you rented with an SLA, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index af171996..d08fc64e 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -36,7 +36,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. 2. In **Search filters** (left bar), set **Reliability target**. If that control is missing, SLA is not available in the console right now. Rent without it, or contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai. 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. -4. Hover over the offer's price and confirm an **SLA Fee** line in the breakdown. That line means this offer will be rented with an SLA at your target when you click **RENT**. If an offer shows no **SLA Fee** line, renting it gives you no SLA. Then click **RENT**. +4. Hover over the offer's price and confirm an **SLA Fee** line, then click **RENT**. That line means this offer will be rented with an SLA at your target. If an offer shows no **SLA Fee** line, renting it gives you no SLA. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. 6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), open **Account → Billing → Charges** (not Invoices). Each UTC day has one net SLA row: the fee minus any service credit. If the credit is larger than the fee, the row is **Service Credit** (`+$`). Otherwise it is **SLA Fee** (`−$`), and that row can still include a partial credit. You cannot see measured reliability, and you cannot split the fee from the credit. If a day had an outage and you need to know whether a credit was applied, contact support with the instance ID and the UTC date. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). @@ -234,7 +234,7 @@ curl -s -X POST "https://console.vast.ai/api/v0/bundles/" \ The CLI default query is `external=false rentable=true verified=true`. Neither the CLI nor the server filters on `rented`. REST `POST /api/v0/bundles/` drops that key and still returns a `rented` flag on each offer. Drop rows where `rented` is true if you need to hide GPUs you already rent. The response includes `truncated`. When it is `true`, the server cut the result short of `limit`. Narrow the query instead of assuming you saw every offer. -Server-side sort by `dph_total` can put a row with no SLA fee first. Offers whose SLA terms fail validation are left out of the results. They still count against `limit`, so a page can return fewer rows than you asked for. A row that comes back with `slaPremiumPerHour` of `0` while you set `target_reliability` has incomplete SLA terms. Drop it, then sort again. Do not rent it. +Offers whose SLA terms fail validation are left out of the results. A page can still return fewer rows than `limit`. Narrow the query instead of raising `limit`. A row that comes back with `slaPremiumPerHour` of `0` while you set `target_reliability` has incomplete SLA terms. Drop it, then sort again. Do not rent it. ```bash curl ... | jq '.offers | map(select((.search.slaPremiumPerHour // 0) > 0)) | sort_by(.dph_total)' @@ -355,7 +355,7 @@ If you quoted with the CLI (default `--storage` 5), set `--storage` ≥ **8** be When you rent an SLA-backed offer **with a target set**: -1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and the rental end date are fixed for that rental. The host's pricing margin is also fixed, and it is not shown to you. When comparing offers, use the SLA fee line or `dph_total`. An SLA does not extend **Max Duration**. Reaching that end date is not an outage, so no credit is owed for the expiry itself. The host may extend the rental on the same terms. +1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and the rental end date are fixed for that rental. The host's pricing margin is also fixed, and it is not shown to you. When comparing offers, use the SLA fee line or `dph_total`. An SLA does not extend **Max Duration**. Reaching that end date is not an outage, so no credit is owed for the expiry itself. At the end date the instance stops and cannot be restarted. It may be deleted 48 hours later. Copy your data off before then. See [Contract Expiration](/guides/instances/manage-instances#contract-expiration). The host may extend the rental on the same terms. 2. **Charges and settlement** — compute, storage, and the SLA fee accrue while the rental contract is active, **including while the machine is offline**. That is different from a non-SLA rental. The net SLA row (SLA fee minus any service credit) settles once per UTC day. See [Settlement timing](#settlement-timing) and [What you pay during an outage](#what-you-pay-during-an-outage). 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. 4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA fee with no credit. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index 5f9250df..bb4595b7 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -196,7 +196,7 @@ Before buying credit with Stripe you must add a card! ### Am I charged for "Loading" instances? -No, you are not charged when it says "Loading" on a rental without an SLA. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +No, you are not charged for GPU time while an instance says **Loading**, on a rental without an SLA. Storage is still charged. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). ### What happens if my account balance is negative? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 2f7733e6..c61d9f28 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -41,7 +41,7 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong Read [SLA in plain language](#sla-in-plain-language) before this list. 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. -2. Publish once **without** SLA. In **Set Pricing**, leave **Reliability Commitment** (the share of time you commit the machine will be up) at `0`, **Save**, then click **LIST**. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. +2. Publish once **without** SLA. In **Set Pricing**, do not open the SLA controls, then **Save** and click **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. @@ -50,8 +50,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). -8. **Verify now.** In the console, sign in as your separate client account, include unverified machines, set **Reliability target** at or below your commitment, and confirm an **SLA Fee** line. Console search cannot look up a machine by id. If no offer shows that line, contact support before you change the listing. - - **Optional (CLI):** create a client key first ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)), then run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Do not add `expected_reliability>=…` to that query. Confirm `expected_reliability` with `jq`. Optionally rent that offer briefly, then **Destroy** the test instance. +8. **Verify now.** The reliable check is a client API key, not console search. Create the key first ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)), then run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. Console search cannot look up your machine by id, so a missing **SLA Fee** line on some other offer does not mean yours failed. If your machine's offer has no **SLA Fee** line, contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. ## Before you enable SLA @@ -154,7 +153,7 @@ When you list or update a machine, set SLA fields via the host console or `PUT / | Parameter | API field | Backtester alias | What it means | | --- | --- | --- | --- | -| Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.99999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. Set to `0` to disable SLA on new rentals. | +| Reliability commitment | `sla_r_claim` | `r_claim` (the simulated renter target `r_target` defaults to it) | Your advertised belief about machine reliability. Set above `0` to enable SLA. Values are greater than 0 and at most **0.99999** (for example, `0.99` = 99%). Exactly `1.0` is rejected. The API accepts `0` to stop SLA on new rentals. The console control cannot be set to `0`. | | Confidence | `sla_sigma_x` | `p` (different scale — see [backtester](/host/sla-backtester#confidence-values-p)) | Pricing margin built into the SLA fee. **High** is a smaller fee. **Low** is a larger fee. It does not change the credit you owe. Defaults to `0.5` (console **Medium**) only on a **new** ask. When you first enable SLA on an existing listing, send `sla_sigma_x` yourself. Omitting it leaves the stored value empty, so `show machines` reports no confidence. On an ask that already has a stored value, omitting `sla_sigma_x` keeps that value. | ### Advanced: `sla_max_beta` (optional) @@ -232,7 +231,7 @@ For planning, assume a bad day can cost up to one full day of covered compute fo ### SLA on extended contracts -**In the console:** moving the offer end date later, or leaving auto-renew on, extends active SLA rentals and your credit exposure. To limit that, set a fixed end date or unlist. +**In the console:** every **Save** on a machine with active rentals sends the listing end date or auto-renew duration. Any rental that ends sooner, including an SLA contract, is extended to that date, even if you changed only **Reliability Commitment** or **Confidence**. To change SLA terms without extending rentals, use the API and omit both `end_date` and `duration`. **API detail (`create_asks`):** @@ -264,11 +263,15 @@ Disabling SLA on the offer (setting `sla_r_claim` to `0`) prevents new SLA-cover #### Updating SLA on an already-listed machine + +Every console **Save** on a machine with active rentals sends the listing end date or auto-renew duration. Any rental that ends sooner, including SLA contracts, is extended to that date, even if you only changed **Reliability Commitment** or **Confidence**. A console **Save** also sends the Confidence preset (`sla_sigma_x` **High** 0.2, **Medium** 0.5, **Low** 1.0). A custom value you set through the API can be replaced. To change SLA terms without extending rentals, and to keep a custom σ, use the API and omit `end_date` and `duration`. + + If the machine is already **listed**: 1. Open **Host → Machines → Set Pricing → SLA**, set **Reliability Commitment** and **Confidence**, then click **Save**. 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. -3. To stop offering SLA on **new** rentals, set **Reliability Commitment** to `0` and **Save**. On an already-listed machine, **Save** updates the live offer; you do not need to click **LIST** again. Active contracts keep their SLA terms until they end. API users: send the full `create_asks` body with `"sla_r_claim": 0` (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). +3. To stop offering SLA on **new** rentals, use the API. Send `"sla_r_claim": 0` in the full `create_asks` body (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). The console control cannot be set to `0`, and a **Save** that omits SLA fields keeps the current terms. Active contracts keep their locked terms until they end. 4. Verify after listing: - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. - **Search:** `dph_total` includes the SLA fee at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). @@ -346,7 +349,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ }' ``` -Replace `end_date` with the listing's current Unix timestamp from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`, read as 00:00 UTC on that date, not your local time zone. `vastai show earnings --start_date` and `--end_date` are different: bare dates there are parsed in the local time zone of the computer running the CLI. +Replace `CURRENT_END_DATE_UNIX` with the listing's current `end_date` (Unix seconds) from `show machines`, or with a new future timestamp only if you mean to change the offer end. Past dates expire the offer immediately. A later date at the same or lower price extends live contracts. See [Offer End Date](/host/hosting-overview#offer-end-date). Convert a calendar date to Unix seconds: `date -u -d '2030-01-01' +%s` (Linux) or `date -u -j -f '%Y-%m-%d' '2030-01-01' +%s` (macOS). The CLI also accepts `MM/DD/YYYY` via `-e`, read as 00:00 UTC on that date, not your local time zone. `vastai show earnings --start_date` and `--end_date` are different: bare dates there are parsed in the local time zone of the computer running the CLI. Open-ended offers (no `end_date`) combined with SLA expose you to indefinite asymmetric service-credit risk. See [Offer End Date](/host/hosting-overview#offer-end-date). From 8f03f0492f7e29d222fafb46751dd21485c45e58 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 06:58:08 -0700 Subject: [PATCH 233/250] docs(sla): address doc-review consensus (cycle 177) Relist after a Docker upgrade without opening SLA controls, and keep the console verify step for hosts who have no API key. Co-authored-by: Cursor --- host/sla-offers.mdx | 13 +++++++------ host/upgrade-docker-and-packages.mdx | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index c61d9f28..e8c988af 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -48,9 +48,10 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. - **API users:** **Host → Billing** has no per-machine SLA line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn`. Much of it can stay held until the contract ends, so a low week is not by itself a credit. See [Monitoring SLA after listing](#monitoring-sla-after-listing). 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. +7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. If the machine already has rentals, **Save** also extends shorter rentals to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). -8. **Verify now.** The reliable check is a client API key, not console search. Create the key first ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)), then run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. Console search cannot look up your machine by id, so a missing **SLA Fee** line on some other offer does not mean yours failed. If your machine's offer has no **SLA Fee** line, contact support before you change the listing. Optionally rent that offer briefly, then **Destroy** the test instance. +8. **Verify now.** In **Host → Machines**, confirm the machine shows **Listed**, then reopen **Set Pricing → SLA** and confirm your terms are saved. + - **API users (strongest check):** search from a separate client account so you see what renters see. Create the key first ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)), then run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. An empty result can also mean every GPU is rented or the listing is hidden. If neither applies and your offer has no **SLA Fee** line, contact support. Optionally rent that offer briefly, then **Destroy** the test instance. ## Before you enable SLA @@ -282,7 +283,7 @@ In the web console, **Set Pricing → Save** stores SLA settings; clicking **LIS #### Web console SLA preview -In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA** when that section is shown. It is a forward-looking quote, not a historical replay — use the [SLA Backtester](/host/sla-backtester) when you have rental history. If **Set Pricing** has no **SLA** section, use [checklist step 4](#sla-host-checklist). +In the host console, open **Host Machines** → select your machine → **Set Pricing** → **SLA** when that section is shown. That preview replays this machine's rental history. A new machine shows "No historical data available for this machine yet." To see the fee renters are quoted before you have history, use search with `target_reliability`. If **Set Pricing** has no **SLA** section, use [checklist step 4](#sla-host-checklist). ### API (for automation) @@ -722,10 +723,10 @@ When SLA is enabled on an offer, clients see: **Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the reliability commitment. The published reliability commitment appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, use `has_sla=true` or filter on `expected_reliability > 0`; do not use the `reliability` filter as an SLA selector. -Verify after listing — filter the offer you care about; sliced machines often return multiple rows (different `num_gpus`, bid vs on-demand). The CLI may print `Warning: Unrecognized field` for `has_sla`. That warning is harmless: the filter is still sent. Match disk allocation before comparing `dph_total` across channels (CLI default is often 5 GiB; console Search is typically 10 GB; REST examples often use 8 GB `allocated_storage`): +Run that search with a client API key (`$CLIENT_API_KEY`), not your host key. See [checklist step 8](#sla-host-checklist). An empty result can also mean every GPU is rented or the listing is hidden. ```bash -vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw \ +vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY" \ | jq '[.[] | select(.is_bid == false) | {id, num_gpus, dph_total, expected_reliability, reliability}]' ``` @@ -802,7 +803,7 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **Or use CLI/REST below.** Forgiveness is not guaranteed either way. -**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Notice rules are in the note above. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. +**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Notice rules are in the note above. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. A rental that starts after you schedule the window may not get that notice. Budget as if its downtime is not forgiven. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. **`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index 53e22129..e9b1cf82 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -535,7 +535,7 @@ Canceled hold on linux-image-generic-hwe-24.04. ### Relist -Relist from the [Machines page](https://cloud.vast.ai/host/machines/). Re-enter every **Set Pricing** field you wrote down. If the machine had an SLA, relist with **Reliability Commitment** at `0`, run the self-test below, and only then set your SLA terms and click **Save**. If the self-test fails, unlist right away. `vastai list machine` creates the ask without SLA and can reset bandwidth and other fields. See the [`list machine` cautions](/host/cli/list-machine). After 2 to 3 +Relist from the [Machines page](https://cloud.vast.ai/host/machines/). Re-enter every **Set Pricing** field you wrote down. If the machine had an SLA, relist **without** opening the SLA controls: in **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. A relist after an unlist creates a new offer without SLA. Run the self-test below. Only after it passes, open **Set Pricing → SLA**, re-enter your terms, and click **Save**. If the self-test fails, unlist right away. `vastai list machine` creates the ask without SLA and can reset bandwidth and other fields. See the [`list machine` cautions](/host/cli/list-machine). After 2 to 3 minutes: ```bash From 61323b5ef757d474d1e6bd8cd3b5e1fbe085f17a Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 07:05:13 -0700 Subject: [PATCH 234/250] docs(sla): address doc-review consensus (cycle 178) A new machine has no SLA preview until it has rental history, and omitted disk still rents 10 GB. Co-authored-by: Cursor --- api-reference/openapi.yaml | 8 +++++--- api-reference/openapi/yaml/create_instance.yaml | 6 +++--- host/sla-backtester.mdx | 7 ++++--- host/sla-offers.mdx | 8 ++++---- host/upgrade-docker-and-packages.mdx | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index f3dd92cc..a1f8295a 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -1645,9 +1645,11 @@ paths: disk: type: number format: float - minimum: 8 - description: 'Size of local disk partition (in GB). Values below - 8 are raised to 8 with no error. + minimum: 0 + description: 'Disk size in GB. Omitted or 0 becomes 10 GB. Values + from 1 through 7 are raised to 8 with no error. Send the same + number you used as allocated_storage in search so the quoted price + matches the bill. ' target_reliability: diff --git a/api-reference/openapi/yaml/create_instance.yaml b/api-reference/openapi/yaml/create_instance.yaml index 1a9833f2..19df462d 100644 --- a/api-reference/openapi/yaml/create_instance.yaml +++ b/api-reference/openapi/yaml/create_instance.yaml @@ -66,9 +66,9 @@ paths: disk: type: number format: float - minimum: 8 - description: | - Size of local disk partition (in GB). Values below 8 are raised to 8 with no error. + minimum: 0 + description: > + Disk size in GB. Omitted or 0 becomes 10 GB. Values from 1 through 7 are raised to 8 with no error. Send the same number you used as allocated_storage in search so the quoted price matches the bill. target_reliability: type: number format: float diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 4e0e08af..51133ed7 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -12,16 +12,17 @@ How much could SLA settlement cost given your reliability commitment and confide | If you want to… | Use | | --- | --- | -| Preview SLA before your first listing | Web console (**Set Pricing → SLA** on the machine page) — no API key needed | +| Preview SLA on a machine that already has rental history | Web console (**Set Pricing → SLA**) — no API key. A new machine has nothing to replay. | +| New machine, no rental history | No preview of your own fee until you enable SLA. Use the [economics walkthrough](/host/sla-offers#economics-walkthrough) as an estimate. After **Save**, check the **SLA Fee** from a separate client account. | | Simulate historical earnings for one machine | This page's single-machine `curl` example | | Review many machines at once | [Fleet workflow](#fleet-workflow) below (advanced; Linux/macOS + `jq`) | -**Console hosts:** use **Set Pricing → SLA** in the web console to preview SLA fees — you do not need this API. +**Console hosts:** the console preview replays rental history. A new machine shows "No historical data available for this machine yet." You do not need this API to list. Use the [economics walkthrough](/host/sla-offers#economics-walkthrough) before you have history. **API hosts:** this endpoint replays your machine's **real historical compute earnings and uptime** through the same SLA settlement used in production, under the SLA terms you choose. Query parameters `r_claim` (reliability commitment), `p` (confidence), and the optional `r_target` (simulated renter target) are defined under [Query parameters](#query-parameters). -**Don't want to use the API?** The backtester is optional. Use the web console SLA preview and the [economics walkthrough](/host/sla-offers#economics-walkthrough) on SLA Offers to evaluate SLA before listing. +**Don't want to use the API?** The backtester is optional. It needs rental history, and so does the console preview. Before you have history, use the [economics walkthrough](/host/sla-offers#economics-walkthrough). ## When to use it diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index e8c988af..45e35a71 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -13,7 +13,7 @@ The **SLA fee** is that hourly amount. It appears as the **SLA Fee** line in the This page explains how SLA offers work from the host side — what you set, how clients choose an SLA, and what happens when uptime is good or bad. -SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; on bad days, service credits can exceed the fees you collected. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**). +SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; on bad days, service credits can exceed the fees you collected. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**, also needs rental history; a new machine shows "No historical data available for this machine yet"). @@ -45,10 +45,10 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. -5. Preview economics (console SLA panel or [backtester](/host/sla-backtester)). Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. +5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. - **API users:** **Host → Billing** has no per-machine SLA line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn`. Much of it can stay held until the contract ends, so a low week is not by itself a credit. See [Monitoring SLA after listing](#monitoring-sla-after-listing). 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. If the machine already has rentals, **Save** also extends shorter rentals to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. +7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. If the machine already has rentals, **Save** also extends shorter rentals to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). The console cannot set **Reliability Commitment** to `0`. To stop offering SLA on new rentals from the console, unlist, then relist without opening the SLA controls. Write down and re-enter every **Set Pricing** field first. API users can send `sla_r_claim: 0` instead. Active SLA contracts keep their terms either way. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** In **Host → Machines**, confirm the machine shows **Listed**, then reopen **Set Pricing → SLA** and confirm your terms are saved. - **API users (strongest check):** search from a separate client account so you see what renters see. Create the key first ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)), then run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. An empty result can also mean every GPU is rented or the listing is hidden. If neither applies and your offer has no **SLA Fee** line, contact support. Optionally rent that offer briefly, then **Destroy** the test instance. @@ -723,7 +723,7 @@ When SLA is enabled on an offer, clients see: **Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the reliability commitment. The published reliability commitment appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, use `has_sla=true` or filter on `expected_reliability > 0`; do not use the `reliability` filter as an SLA selector. -Run that search with a client API key (`$CLIENT_API_KEY`), not your host key. See [checklist step 8](#sla-host-checklist). An empty result can also mean every GPU is rented or the listing is hidden. +Run that search with a client API key (`$CLIENT_API_KEY`), not your host key. See [checklist step 8](#sla-host-checklist). An empty result can also mean every GPU is rented or the listing is hidden. The CLI may print `Warning: Unrecognized field` for `has_sla`. That warning is harmless: the filter is still sent. Match disk allocation before comparing `dph_total` across channels (CLI default is often 5 GiB; console Search is typically 10 GB; REST examples often use 8 GB `allocated_storage`). ```bash vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY" \ diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index e9b1cf82..3a2e5162 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -6,7 +6,7 @@ description: "Safely upgrade Docker, containerd, the NVIDIA stack, and other sys -This upgrade runs only when the machine has no running or stored instances. A maintenance window notifies renters. It does not remove their instances, and it does not stop new rentals. The machine is empty only after the latest rental end date on **Host → Machines** has passed, or after renters destroy their instances. Schedule the window after that date. To stop new rentals while you wait, write down every **Set Pricing** field and then unlist (see [Severe outage](/host/sla-offers#severe-outage)). If the window starts and instances are still on the machine, do not upgrade. A 48-hour lead is a courtesy to renters, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. +Run this upgrade only when the machine has no running or stored instances. Nothing in the upgrade checks for instances for you. A maintenance window notifies renters. It does not remove their instances, and it does not stop new rentals. The machine is empty only after the latest rental end date on **Host → Machines** has passed, or after renters destroy their instances. Schedule the window after that date. To stop new rentals while you wait, write down every **Set Pricing** field and then unlist (see [Severe outage](/host/sla-offers#severe-outage)). If the window starts and instances are still on the machine, do not upgrade. A 48-hour lead is a courtesy to renters, not an SLA forgiveness cutoff. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). Downtime outside a window counts against your reliability and, on an SLA rental, can lead to service credits. You are responsible for the maintenance and any resulting interruption. From e56defe8802460ebd9eae3ea877c3e4b14cd3bda Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 07:13:18 -0700 Subject: [PATCH 235/250] docs(sla): address doc-review consensus (cycle 179) The fleet quota check was matching an error code the CLI never prints, and hosts were told to read an SLA fee the CLI cannot show. Co-authored-by: Cursor --- cli/rate-limits.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 3 ++- guides/reference/billing.mdx | 2 +- host/sla-offers.mdx | 17 +++++++++-------- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/cli/rate-limits.mdx b/cli/rate-limits.mdx index 12ef4e91..83aa8e97 100644 --- a/cli/rate-limits.mdx +++ b/cli/rate-limits.mdx @@ -33,7 +33,7 @@ For the full breakdown, see [How rate limits are applied](/api-reference/rate-li HTTP 429 comes in two families. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors#rate-limit-response-behavior). -- Rent, show-instances, `create_asks`, and `show earnings` (machine earnings) do not return the JSON `{"error": …}` body. With a default Accept header the body is usually HTML. Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. +- Rent, show-instances, `create_asks`, and `show earnings` (machine earnings) do not return the JSON `{"error": …}` body. With a default Accept header the body is usually HTML. Search, charges, the other earnings routes, schedule maintenance, and the SLA backtester return JSON. A short limit uses `"error": "HTTPTooManyRequests"`. A daily search quota hit uses `"error": "search_quota_exceeded"` and a `Retry-After` that can be hours. The CLI prints only the server `msg` (`Daily search row quota exhausted`), not that `error` code. In scripts, match HTTP 429 plus the message text. - Both kinds include a `Retry-After` header. Detect a limit by HTTP status 429. The CLI never reads `Retry-After`. The CLI never reads `Retry-After`. With the default of 3 attempts, its retries finish in under a second. If your script calls the API directly, wait at least `Retry-After` when it is present. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d08fc64e..d5756ead 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -374,7 +374,7 @@ During an outage the Instances price popover may say "Machine is offline. You're **Stop vs destroy.** -- **Stop:** How **Stop** and **Loading** time are billed on an SLA rental is not guaranteed. Budget as if both can still be charged. Only **Destroy** reliably ends GPU and SLA charges, and Destroy deletes the disk. Check **Charges** the next UTC day. If GPU or SLA charges are still there and you do not need the disk, **Destroy**. +- **Stop:** On an SLA rental, do not rely on **Stop** to pause billing. Budget as if GPU time and the SLA fee continue while the instance is Stopped or Loading. To be sure charges end, **Destroy** the instance. Destroy deletes the disk, so copy off anything you need first. Check **Charges** the next UTC day. - **Zero balance:** At a $0.00 balance, a stopped SLA instance can keep accruing charges. If you have no saved card, the instance and its data are scheduled for deletion. If you have a saved card, auto-stop is not a reliable way to end those charges. Destroy the instance if you do not plan to resume. See [Negative Balances](/guides/reference/billing#negative-balances). - **Downtime you cause:** Contact support before you count on a service credit for your own Stop or reboot, a bad image, a container crash, or a stop at zero balance. - **Final settlement:** The net SLA row still posts when the contract closes. @@ -400,6 +400,7 @@ Using the H100 example ($84/day compute, ~$0.97/day SLA fee, target 95%, host re | Scenario | Approx. SLA fee | Approx. service credit | Credit minus SLA fee | | --- | --- | --- | --- | | Above target (excellent / good day) | ~$0.97/day | $0 | **−$0.97** (you paid the SLA fee) | +| Short outage that still meets the target (about 1 hour offline) | ~$0.97/day | $0 | **−$0.97**, plus about $3.50 of GPU billed for that hour (a non-SLA rental is not billed for it) | | Below target (~93–94% for the day) | ~$0.97/day | ~$42 | **+$41** (credit after the SLA fee) | | Severe shortfall (~90% or less) | ~$0.97/day | ~$84 | **+$83** | diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index bb4595b7..41feb6bc 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -196,7 +196,7 @@ Before buying credit with Stripe you must add a card! ### Am I charged for "Loading" instances? -No, you are not charged for GPU time while an instance says **Loading**, on a rental without an SLA. Storage is still charged. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +On a rental **without** an SLA, you are not charged for GPU time while an instance shows **Loading**. Storage is still charged. On an **SLA** rental, budget as if Loading time is charged. To be sure charges end, **Destroy** the instance. Destroy deletes the disk. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). ### What happens if my account balance is negative? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 45e35a71..fda093f7 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -51,7 +51,8 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. If the machine already has rentals, **Save** also extends shorter rentals to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). The console cannot set **Reliability Commitment** to `0`. To stop offering SLA on new rentals from the console, unlist, then relist without opening the SLA controls. Write down and re-enter every **Set Pricing** field first. API users can send `sla_r_claim: 0` instead. Active SLA contracts keep their terms either way. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** In **Host → Machines**, confirm the machine shows **Listed**, then reopen **Set Pricing → SLA** and confirm your terms are saved. - - **API users (strongest check):** search from a separate client account so you see what renters see. Create the key first ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)), then run `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. An empty result can also mean every GPU is rented or the listing is hidden. If neither applies and your offer has no **SLA Fee** line, contact support. Optionally rent that offer briefly, then **Destroy** the test instance. + - **CLI:** search from a separate client account ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)): `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. The CLI cannot send `target_reliability`, so its `dph_total` does **not** include the SLA fee and it never shows an **SLA Fee** line. An empty result can also mean every GPU is rented or the listing is hidden. + - **SLA fee:** check it in the console from that same client account (**Search → Reliability target**), then confirm the **SLA Fee** line on your offer. A REST search that sends `target_reliability` also returns the fee-inclusive `dph_total`. If the console shows no **SLA Fee** line at a target at or below your commitment, contact support. Optionally rent that offer briefly, then **Destroy** the test instance. ## Before you enable SLA @@ -421,7 +422,7 @@ Use this loop only to restore SLA offers that no longer appear in search on mach Each live PUT resends the offer's `end_date` (or `duration`). Any active rental that ends **before** that date is extended to it, which also extends your service-credit exposure. This cannot be undone, and `DRY_RUN=1` does not show which contracts will be affected. No documented API shows each rental's end date, so you cannot confirm in advance which rentals a later `end_date` will extend. Assume a live run extends any shorter rental, and read `upd_contracts` afterwards (it may not list contracts extended a few minutes later). -The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute for the account, not for each API key. See [How rate limits are applied](/api-reference/rate-limits-and-errors#how-rate-limits-are-applied). The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped, unless the error is `search_quota_exceeded`. That daily quota can take hours to reset, so the loop stops. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. +The loop needs two keys: a listing key (`machine_write` and `machine_read`, `VAST_API_KEY`) and a separate search key with `misc` (`SEARCH_API_KEY`). Offer search is about 10 requests per minute for the account, not for each API key. See [How rate limits are applied](/api-reference/rate-limits-and-errors#how-rate-limits-are-applied). The loop runs local checks first and only searches machines that pass them, so skipped machines use none of that budget. If a search fails or is not a JSON array, that machine is skipped, unless the CLI message says the daily search quota is exhausted (`Daily search row quota exhausted`). The CLI prints that message, not the REST `error` code `search_quota_exceeded`. The quota can take hours to reset, so the loop stops. A failed search never becomes a re-list. An empty array can also mean every GPU is rented. The loop skips a machine unless `current_rentals_resident` is `0`. That count includes stopped rentals. A PUT that resends `end_date` extends every shorter rental on the machine, whether its instance is running or stopped. Before `DRY_RUN=0`, confirm on **Host → Machines** that each allowlisted machine has no rentals at all. Stopped rentals count. The loop does not turn an SLA on for new machines. Enable an SLA on each machine first (console **Set Pricing → SLA**, or a per-machine `PUT /api/v0/machines/create_asks/` with `sla_r_claim` and `sla_sigma_x`). The loop only considers machines that are `listed` and already have `sla_reliability_claim > 0`. It skips a machine whose confidence was never stored. Fix those with the check under [Validation rules](#validation-rules) before you re-list. `show machines` returns confidence only as a label. Set `SIGMA_MAP` (`id=σ`, space-separated) from your own record before `DRY_RUN=0`. A live run skips any machine that is not in the map, because a new ask would otherwise reset `sla_sigma_x` to `0.5`. Resending the same σ on an existing ask is harmless. The post-run `WARN` is only a backstop. @@ -550,8 +551,8 @@ for id in $(echo "$machines" | jq -r '.machines[].id'); do sleep 6 out=$(vastai search offers "machine_id=$id verified=any has_sla=true" --raw --retry 1 --api-key "$SEARCH_API_KEY" 2>"$BTERR") if ! printf '%s' "$out" | jq -e 'type == "array"' >/dev/null; then - if grep -q 'search_quota_exceeded' "$BTERR"; then - echo "ABORT: daily search quota exhausted (search_quota_exceeded). Retry-After can be hours. Re-run later." >&2 + if grep -qiE 'search_quota_exceeded|quota exhausted' "$BTERR"; then + echo "ABORT: daily search quota exhausted. The CLI prints the server message, not the error code. Retry-After can be hours. Re-run later." >&2 exit 1 fi echo "skip $id: search failed (missing misc permission or HTTP 429); see $BTERR" >&2 @@ -717,13 +718,13 @@ If you omit `r_target`, the backtester sets the renter target equal to your reli When SLA is enabled on an offer, clients see: -- **`dph_total`** — total $/hour including the SLA fee at their `target_reliability` (authoritative for client-visible all-in pricing). +- **`dph_total`** — total $/hour. It includes the SLA fee **only** when the search sends `target_reliability` (console or REST). CLI searches cannot send it, so CLI `dph_total` excludes the fee. - **`expected_reliability`** — your advertised reliability commitment (maps to `sla_r_claim`). - **`reliability` / `reliability2`** — historical machine reliability scores, **not** your reliability commitment. **Filter vs response field:** In search queries, the `reliability` filter uses the machine's historical reliability score — not the reliability commitment. The published reliability commitment appears in responses as `expected_reliability`. To select SLA-listed offers programmatically, use `has_sla=true` or filter on `expected_reliability > 0`; do not use the `reliability` filter as an SLA selector. -Run that search with a client API key (`$CLIENT_API_KEY`), not your host key. See [checklist step 8](#sla-host-checklist). An empty result can also mean every GPU is rented or the listing is hidden. The CLI may print `Warning: Unrecognized field` for `has_sla`. That warning is harmless: the filter is still sent. Match disk allocation before comparing `dph_total` across channels (CLI default is often 5 GiB; console Search is typically 10 GB; REST examples often use 8 GB `allocated_storage`). +Run that search with a client API key (`$CLIENT_API_KEY`), not your host key. See [checklist step 8](#sla-host-checklist). An empty result can also mean every GPU is rented or the listing is hidden. The CLI may print `Warning: Unrecognized field` for `has_sla`. That warning is harmless: the filter is still sent. Do not compare CLI `dph_total` with the console or REST total: the CLI figure excludes the SLA fee. When you do compare console and REST, use the same disk size (console Search is typically 10 GB; REST examples often use 8 GB `allocated_storage`). ```bash vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY" \ @@ -861,7 +862,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. - 6. Relist only if you unlisted in step 3. Re-enter the terms from step 2, confirm the SLA fee preview, **Save**, then **LIST**. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. + 6. Relist only if you unlisted in step 3. Relist **without** SLA first: leave the SLA controls closed, click **Save**, then **LIST**, and run the self-test (same order as [Upgrade Docker and packages → Relist](/host/upgrade-docker-and-packages#relist)). Re-enter the SLA terms and click **Save** only after the self-test passes. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. **API** @@ -886,7 +887,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Relist with every field resent.** Relisting after an unlist creates a new ask, so stored values do not carry over. Send all of these in one `create_asks` request, using the values you recorded before unlisting: `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `sla_r_claim`, `sla_sigma_x`, `credit_discount_max`, `price_min_bid`, and `"vol_size": 0` unless you want a volume offer. An omitted `credit_discount_max` becomes `0.4`. An omitted `sla_sigma_x` becomes `0.5`. `show machines` never returns the exact `sla_sigma_x`. Sending `end_date` or `duration` extends every active rental that ends sooner. No documented API shows each rental's end date. Check **Host → Machines** for the latest rental end date before you choose the `end_date` or `duration` to send. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Relist without SLA, self-test, then turn SLA back on.** Relisting after an unlist creates a new ask, so stored values do not carry over. First send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. Run `vastai self-test machine MACHINE_ID`. Only after it passes, send a second `create_asks` with `sla_r_claim` and `sla_sigma_x` from your notes. Do not omit `sla_sigma_x` on that second request: an omitted value on a new ask becomes `0.5`. Leave `end_date` and `duration` off the second request so you do not extend rentals again. Sending `end_date` or `duration` extends every active rental that ends sooner. No documented API shows each rental's end date. Check **Host → Machines** for the latest rental end date before you choose the `end_date` or `duration` on the first request. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing From f1fc1cfde29caa1c3b35f568e3f9748bdd118606 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 07:26:44 -0700 Subject: [PATCH 236/250] docs(sla): address doc-review consensus (cycle 180) The outage relist was turning SLA back on with a partial body that resets storage price and auto-renew. Co-authored-by: Cursor --- host/set-maintenance-window.mdx | 4 ++-- host/sla-offers.mdx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/host/set-maintenance-window.mdx b/host/set-maintenance-window.mdx index 0e119314..f99ecc8b 100644 --- a/host/set-maintenance-window.mdx +++ b/host/set-maintenance-window.mdx @@ -109,7 +109,7 @@ switch — you can schedule a single window for all of them in one pass. -A bulk request covers at most 100 machines. Select fewer and repeat if you have +Console **Bulk Edit** covers at most 100 machines per request. The CLI and the single-machine REST route schedule one machine per call. Select fewer and repeat if you have more than that. @@ -140,7 +140,7 @@ Contact support if one needs to be removed. ### Start time -The start must be in the future, and no more than a year out. +In the console, the start must be in the future, and no more than a year out. The single-machine CLI and REST route does not apply that check. For planned work, still pick a future time. ### Duration diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index fda093f7..1bea2eda 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -273,7 +273,7 @@ If the machine is already **listed**: 1. Open **Host → Machines → Set Pricing → SLA**, set **Reliability Commitment** and **Confidence**, then click **Save**. 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. -3. To stop offering SLA on **new** rentals, use the API. Send `"sla_r_claim": 0` in the full `create_asks` body (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). The console control cannot be set to `0`, and a **Save** that omits SLA fields keeps the current terms. Active contracts keep their locked terms until they end. +3. To stop offering SLA on **new** rentals, use the API. Send `"sla_r_claim": 0` in the full `create_asks` body (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). The console control cannot be set to `0`, and a **Save** that omits SLA fields keeps the current terms. **Console-only hosts:** write down every **Set Pricing** field, unlist, then relist without opening the SLA controls (see [SLA host checklist](#sla-host-checklist), step 7). Active contracts keep their locked terms until they end. 4. Verify after listing: - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. - **Search:** `dph_total` includes the SLA fee at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). @@ -862,7 +862,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. - 6. Relist only if you unlisted in step 3. Relist **without** SLA first: leave the SLA controls closed, click **Save**, then **LIST**, and run the self-test (same order as [Upgrade Docker and packages → Relist](/host/upgrade-docker-and-packages#relist)). Re-enter the SLA terms and click **Save** only after the self-test passes. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. + 6. Relist only if you unlisted in step 3. Relist **without** SLA first: leave the SLA controls closed, click **Save**, then **LIST**, and run the self-test (same order as [Upgrade Docker and packages → Relist](/host/upgrade-docker-and-packages#relist)). Re-enter the SLA terms and click **Save** only after the self-test passes. That second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. **API** @@ -887,7 +887,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Relist without SLA, self-test, then turn SLA back on.** Relisting after an unlist creates a new ask, so stored values do not carry over. First send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. Run `vastai self-test machine MACHINE_ID`. Only after it passes, send a second `create_asks` with `sla_r_claim` and `sla_sigma_x` from your notes. Do not omit `sla_sigma_x` on that second request: an omitted value on a new ask becomes `0.5`. Leave `end_date` and `duration` off the second request so you do not extend rentals again. Sending `end_date` or `duration` extends every active rental that ends sooner. No documented API shows each rental's end date. Check **Host → Machines** for the latest rental end date before you choose the `end_date` or `duration` on the first request. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Relist without SLA, self-test, then turn SLA back on.** Relisting after an unlist creates a new ask, so stored values do not carry over. First send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. Run `vastai self-test machine MACHINE_ID`. Only after it passes, send a second `PUT /api/v0/machines/create_asks/` with the full body from [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body), not just the SLA fields: `price_disk`, `price_inetu`, `price_inetd`, `credit_discount_max`, `min_chunk`, `hidden_listing`, `"vol_size": 0`, plus `sla_r_claim` and `sla_sigma_x` from your notes. Omitting those listing fields resets them (`price_disk` goes back to $0.10, a hidden listing becomes public, and a missing `vol_size` can create a volume offer). On a fixed end date, omit `end_date` and `duration` on that second request so no rental is extended again. On a rolling listing, omitting `duration` turns auto-renew off. Resend the same integer `duration` if you want auto-renew to stay on. That duration is measured from now, so the second request can extend shorter rentals a bit further than the first. Sending a later `end_date` extends every active rental that ends sooner. No documented API shows each rental's end date. Check **Host → Machines** for the latest rental end date before you choose the `end_date` or `duration` on the first request. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing From a8c4b1ceed1533688d8d1cb843cf44ec45bcbf29 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 07:36:05 -0700 Subject: [PATCH 237/250] docs(sla): address doc-review consensus (cycle 181) Hosts were told to stay listed through maintenance, and to turn SLA on before destroying the test rental. Co-authored-by: Cursor --- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/hosting-overview.mdx | 2 +- host/set-maintenance-window.mdx | 2 +- host/sla-offers.mdx | 15 ++++++++++----- snippets/host/cli/schedule-maint.mdx | 2 +- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index bcfa519c..0bbe5ce4 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -61,7 +61,7 @@ All stats shown are the portion of the total machine rented. - **SLA (optional):** On-demand offers may include an optional SLA (interruptible/spot has no SLA). Set **Reliability target** in the left Search filters before you click **RENT**. Then confirm an **SLA Fee** line in the price breakdown. An offer that shows the host's reliability commitment does not put you on the SLA until you rent with that target set. See [SLA](/guides/instances/choosing/sla-coverage#in-the-web-console). -To rent with an SLA, set **Reliability target** in **Search filters** (left bar), confirm the price breakdown shows an **SLA Fee** line, then click **RENT**. No **SLA Fee** line means no SLA. If that line is missing on every offer, contact support. CLI/API query settings do not carry over into the console. For CLI and API limits, see [SLA](/guides/instances/choosing/sla-coverage). +To rent with an SLA, set **Reliability target** in **Search filters** (left bar), confirm the price breakdown shows an **SLA Fee** line, then click **RENT**. To rent without an SLA, clear **Reliability target**. While it is set, offers without an SLA are hidden. No **SLA Fee** line means no SLA. If that line is missing on every offer, contact support. CLI/API query settings do not carry over into the console. For CLI and API limits, see [SLA](/guides/instances/choosing/sla-coverage). ## Instance Disk Size diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d5756ead..d1525d64 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -34,7 +34,7 @@ Hosts who want the same idea from the listing side can read [SLA in plain langua Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) has credit or a payment method, add an SSH key under **Account → Keys** (or plan to use a Jupyter/notebook template that does not require SSH; see [Keys](/guides/reference/keys)), and pick a [template](/guides/instances/choosing/templates) in Search (see [Finding & Renting](/guides/instances/choosing/find-and-rent)). 1. Open [Search](https://cloud.vast.ai/create/) with **On-demand** selected. -2. In **Search filters** (left bar), set **Reliability target**. If that control is missing, SLA is not available in the console right now. Rent without it, or contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai. +2. In **Search filters** (left bar), set **Reliability target**. If that control is missing, SLA is not available in the console right now. Rent without it, or contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai. To rent without an SLA later, clear **Reliability target**. While it is set, offers without an SLA are hidden. 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line, then click **RENT**. That line means this offer will be rented with an SLA at your target. If an offer shows no **SLA Fee** line, renting it gives you no SLA. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. @@ -99,7 +99,7 @@ Bandwidth is billed separately, based on usage (`inet_*` rates), and is **not** | Host reliability commitment | Maximum reliability the host advertises on the listing (`expected_reliability`). Higher commitment → lower SLA fee at a given reliability target | | Host confidence | Host-side pricing setting that affects SLA fee size. **You do not set this** — the host chooses it, and it is **not shown on offer cards**. Compare offers using `dph_total` or the SLA fee line in the price breakdown | -**Rule of thumb:** your reliability target must be **at or below** the host's reliability commitment. Offers whose commitment is below your target are not shown in search and cannot be rented. At the same target, a host with a higher commitment charges a lower SLA fee. In search results, the host reliability commitment appears as **expected reliability** on the offer (API: `expected_reliability`) — not the Reliability Score on the card. +**Requirement:** your reliability target must be **at or below** the host's reliability commitment. Offers whose commitment is below your target are not shown in search and cannot be rented. At the same target, a host with a higher commitment charges a lower SLA fee. In search results, the host reliability commitment appears as **expected reliability** on the offer (API: `expected_reliability`) — not the Reliability Score on the card. ### Example: H100 at $3.50/hr GPU diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 2fe49396..b0b7a880 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -257,7 +257,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **Planned work:** stay listed and [schedule a maintenance window](/host/sla-offers#scheduled-maintenance). +- **Planned work:** schedule a [maintenance window](/host/sla-offers#scheduled-maintenance) so current renters get notice. Staying listed lets new rentals start, and a rental that starts after you schedule may not get forgiveness for that window. To block new rentals, write down **Set Pricing** and unlist ([Severe outage](/host/sla-offers#severe-outage)). - **Outage, machine still online, and you need to stop new rentals:** you may unlist. Before you unlist, record every **Set Pricing** field: GPU, storage, and bandwidth prices; minimum GPUs; reserved discount (omitted on a new ask becomes `0.4`); min bid; offer end date and auto-renew duration; whether the listing is **hidden**; and **Reliability Commitment** and **Confidence**. Unlisting does not change existing rentals, but it drops the SLA ask. A blank bandwidth price publishes at $0 when you relist. When you relist, read [Severe outage step 6](/host/sla-offers#severe-outage) before choosing an end date: check the latest rental end date on **Host → Machines**, then wait until it passes or accept that shorter rentals will be extended. Pick the path that matches your situation: diff --git a/host/set-maintenance-window.mdx b/host/set-maintenance-window.mdx index f99ecc8b..da512962 100644 --- a/host/set-maintenance-window.mdx +++ b/host/set-maintenance-window.mdx @@ -13,7 +13,7 @@ unlist the machine, or block new rentals. You still take the machine down yourse when the window arrives. -**Offering an SLA?** More notice forgives more of a window, and longer windows are forgiven less. The 24-hour default start is not a forgiveness threshold, and notice is not guaranteed to forgive the downtime fully. Schedule as far ahead as you can and keep the duration as short as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). +**Offering an SLA?** More notice forgives more of a window, and longer windows are forgiven less. The 24-hour default start is not a forgiveness threshold, and notice is not guaranteed to forgive the downtime fully. A window does not block new rentals. A rental that starts after you schedule may not get forgiveness for that window. Schedule as far ahead as you can and keep the duration as short as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 1bea2eda..6458c043 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -41,14 +41,19 @@ Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong Read [SLA in plain language](#sla-in-plain-language) before this list. 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. -2. Publish once **without** SLA. In **Set Pricing**, do not open the SLA controls, then **Save** and click **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, or if you want SLA earnings for one machine. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. +2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. +3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, if you want SLA earnings for one machine, or if you need `vastai self-test machine` before turning SLA back on after an outage. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. - - **API users:** **Host → Billing** has no per-machine SLA line. After you enable SLA, GPU earnings can drop because that compute is released as `sla_earn`. Much of it can stay held until the contract ends, so a low week is not by itself a credit. See [Monitoring SLA after listing](#monitoring-sla-after-listing). + - **All hosts:** After you enable SLA, GPU earnings in **Host → Billing** can drop. That compute is paid out later as SLA earnings, and much of it can stay held until the contract ends. A lower total is not by itself a credit. + - **API users:** Read the held amount as `sla_earn`. See [Monitoring SLA after listing](#monitoring-sla-after-listing). 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. -7. Enter **Reliability Commitment** and **Confidence**. On a machine that is already listed, **Save** publishes SLA to live renters immediately. If the machine already has rentals, **Save** also extends shorter rentals to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). The console cannot set **Reliability Commitment** to `0`. To stop offering SLA on new rentals from the console, unlist, then relist without opening the SLA controls. Write down and re-enter every **Set Pricing** field first. API users can send `sla_r_claim: 0` instead. Active SLA contracts keep their terms either way. Start **Confidence** at **Low** unless you have rental history. The commitment field is a percent (it ends with `%`; type `99` for 99%). Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. +7. **Enable SLA.** + - **Do this:** In **Set Pricing → SLA**, enter **Reliability Commitment** as a percent (the field ends with `%`; type `99` for 99%). Set **Confidence**. Start at **Low** unless you have rental history. Then click **Save**. + - **What Save also does:** On a machine that is already listed, **Save** publishes immediately and extends every shorter rental to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). + - **Turning SLA off later:** The console cannot set the commitment to `0`. Before you unlist, write down every **Set Pricing** field, then relist without opening the SLA controls. API users can send `"sla_r_claim": 0` instead. Active SLA contracts keep their terms either way. See [Updating SLA on an already-listed machine](#updating-sla-on-an-already-listed-machine). + - Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** In **Host → Machines**, confirm the machine shows **Listed**, then reopen **Set Pricing → SLA** and confirm your terms are saved. - **CLI:** search from a separate client account ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)): `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. The CLI cannot send `target_reliability`, so its `dph_total` does **not** include the SLA fee and it never shows an **SLA Fee** line. An empty result can also mean every GPU is rented or the listing is hidden. @@ -862,7 +867,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. - 6. Relist only if you unlisted in step 3. Relist **without** SLA first: leave the SLA controls closed, click **Save**, then **LIST**, and run the self-test (same order as [Upgrade Docker and packages → Relist](/host/upgrade-docker-and-packages#relist)). Re-enter the SLA terms and click **Save** only after the self-test passes. That second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. + 6. Relist only if you unlisted in step 3. Relist **without** SLA first: leave the SLA controls closed, click **Save**, then **LIST**, and run `vastai self-test machine MACHINE_ID` (this needs the CLI; see [Self-test](/host/upgrade-docker-and-packages#self-test)). Re-enter the SLA terms and click **Save** only after the last line reads `Test completed successfully.` That second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. **API** diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 4d11e3b4..495db183 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -29,7 +29,7 @@ vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_ca - One of `power`, `internet`, `disk`, `gpu`, `software`, `other`. Always pass it: if you omit it, the CLI sends `"not provided"`, which the API rejects with HTTP 400. Use `other` when nothing else fits. + One of `power`, `internet`, `disk`, `gpu`, `software`, `other`. Always pass it: if you omit it, the CLI sends `"not provided"`, which the API rejects with HTTP 400. The Python SDK does the same unless you pass `category=`. Use `other` when nothing else fits. From 4a7865fc053476465fee7eaa808869e853d4cd02 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 07:46:39 -0700 Subject: [PATCH 238/250] docs(sla): address doc-review consensus (cycle 182) show maints needs instance_read, and the post-outage self-test will not start while the machine is still rented. Co-authored-by: Cursor --- api-reference/openapi.yaml | 10 ++++---- api-reference/openapi/yaml/show_charges.yaml | 5 ++-- api-reference/permissions.mdx | 6 +++-- guides/reference/billing.mdx | 2 +- guides/reference/faq/billing.mdx | 2 +- host/set-maintenance-window.mdx | 5 ++-- host/sla-offers.mdx | 24 ++++++++++++++------ snippets/host/cli/schedule-maint.mdx | 2 +- 8 files changed, 35 insertions(+), 21 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index a1f8295a..35a72e2e 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -7568,10 +7568,12 @@ paths: type: number format: float description: 'Charge amount for this item. For type - "sla", this is the SLA fee minus any service credit - for the settled UTC day. A positive amount is a - net fee. A negative amount is a net credit. The - console Charges tab shows the opposite sign. + "sla", this is the net SLA amount for the whole + query window (fee minus credit), not one row per + day. Query one UTC day at a time for a daily figure. + A positive amount is a net fee. A negative amount + is a net credit. The console Charges tab shows the + opposite sign. ' example: 37.344 diff --git a/api-reference/openapi/yaml/show_charges.yaml b/api-reference/openapi/yaml/show_charges.yaml index 9f278fee..67d0e597 100644 --- a/api-reference/openapi/yaml/show_charges.yaml +++ b/api-reference/openapi/yaml/show_charges.yaml @@ -172,8 +172,9 @@ paths: type: number format: float description: > - Charge amount for this item. For type "sla", this is the SLA fee - minus any service credit for the settled UTC day. A positive amount + Charge amount for this item. For type "sla", this is the net SLA amount + for the whole query window (fee minus credit), not one row per day. + Query one UTC day at a time for a daily figure. A positive amount is a net fee. A negative amount is a net credit. The console Charges tab shows the opposite sign. example: 37.344 diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 7e89c7ec..2720f7f4 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -138,7 +138,7 @@ Each `items[]` entry is one net `type: "sla"` amount for the whole query window **Host — list, backtest, and earnings.** -Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` can change a listing but cannot read current values, backtest, or read earnings. Pair it with `machine_read` so a script can read the current listing, then send a full body, because omitted fields reset. `machine_read` also covers the backtester. Add `billing_read` for earnings. For cron, prefer a `billing_read` key for monitoring and a separate `machine_write` + `machine_read` key for listing changes. +Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do not copy the renter recipe. `machine_write` can change a listing but cannot read current values, backtest, or read earnings. Pair it with `machine_read` so a script can read the current listing, then send a full body, because omitted fields reset. `machine_read` also covers the backtester. Add `billing_read` for earnings. Add `instance_read` if the key will run `vastai show maints`. For cron, prefer a `billing_read` key for monitoring and a separate `machine_write` + `machine_read` key for listing changes. **Workflow summary:** Backtest (optional) → `create_asks` with SLA fields → monitor earnings; host-side settlement is separate from marketplace score. @@ -151,7 +151,8 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do "api": { "machine_read": {}, "machine_write": {}, - "billing_read": {} + "billing_read": {}, + "instance_read": {} } } ``` @@ -171,6 +172,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | List or update an SLA offer (`PUT /api/v0/machines/create_asks/`) | `machine_write` | **Set Pricing → SLA** → **Save**. First publish: **Save** → **LIST**. Already listed: **Save** only ([Web console](/host/sla-offers#web-console)) | | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | +| Confirm windows (`vastai show maints`) | `instance_read` | **Machine Maintenances** or **Scheduled Maintenances**. | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings (console billing needs no API key; API earnings need `billing_read`). Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | | Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10` (`verified=any` is often required when checking your own machine). | diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index 41feb6bc..efac79aa 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -83,7 +83,7 @@ You are charged the base active rental cost for every second your instance is in You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals keep billing for GPU compute, storage, and the SLA fee during downtime, as if the instance were still running. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are not charged active rental or storage costs for instances that are currently offline. Exception: on an SLA rental, budget as if GPU compute, storage, and the SLA fee continue while the instance is offline, stopped, or loading. **Destroy** is the reliable way to end those charges. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). To see a pricing breakdown on your current instances within your Instance page in the console or from offers on the Search page you can hover over the price to see pricing details. diff --git a/guides/reference/faq/billing.mdx b/guides/reference/faq/billing.mdx index 87174023..9fa69e06 100644 --- a/guides/reference/faq/billing.mdx +++ b/guides/reference/faq/billing.mdx @@ -33,7 +33,7 @@ You are charged the storage cost (which depends on the size of your storage allo Stopping an instance does not avoid storage costs. You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. Exception: SLA rentals keep billing for GPU compute, storage, and the SLA fee during downtime, as if the instance were still running. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are not charged active rental or storage costs for instances that are currently offline. Exception: on an SLA rental, budget as if GPU compute, storage, and the SLA fee continue while the instance is offline, stopped, or loading. **Destroy** is the reliable way to end those charges. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). ### What is the billing frequency? diff --git a/host/set-maintenance-window.mdx b/host/set-maintenance-window.mdx index da512962..be027e41 100644 --- a/host/set-maintenance-window.mdx +++ b/host/set-maintenance-window.mdx @@ -109,8 +109,7 @@ switch — you can schedule a single window for all of them in one pass. -Console **Bulk Edit** covers at most 100 machines per request. The CLI and the single-machine REST route schedule one machine per call. Select fewer and repeat if you have -more than that. +Console **Bulk Edit** covers at most 100 machines per request. If you have more, select fewer and repeat. The CLI and REST schedule one machine per call. --- @@ -140,7 +139,7 @@ Contact support if one needs to be removed. ### Start time -In the console, the start must be in the future, and no more than a year out. The single-machine CLI and REST route does not apply that check. For planned work, still pick a future time. +Use a start time in the future, and no more than a year out. For an outage already underway, one minute from now is enough. ### Duration diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 6458c043..994bdcba 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -25,7 +25,7 @@ SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. -Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong). Skip [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) and API automation unless you manage many machines with scripts. The console shows fleet-wide totals, with SLA folded into earnings. Per-machine SLA amounts need the CLI and an API key with `billing_read`. +Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong). Skip [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) and API automation unless you manage many machines with scripts. The console shows fleet-wide totals, with SLA folded into earnings. Per-machine SLA amounts need the CLI and an API key with `billing_read`. Outage recovery also needs the CLI: turning SLA back on requires `vastai self-test machine`. Install it before you enable SLA (checklist step 3). | Goal | Start here | @@ -42,7 +42,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) if you schedule maintenance from the command line, if you want SLA earnings for one machine, or if you need `vastai self-test machine` before turning SLA back on after an outage. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. +3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. Turning SLA back on after an outage requires `vastai self-test machine`. You also need the CLI for maintenance from the command line and for per-machine SLA earnings. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. @@ -334,7 +334,7 @@ Any active rental that ends **before** the `end_date` you send is extended to th #### Full listing update (existing ask) -When you also need to refresh GPU price or move `end_date`. **This example sends `end_date`.** Every shorter active rental is extended to that timestamp. Omit `end_date` if you only want to change price or SLA terms. +Use this body when you also need to refresh the GPU price or move `end_date`. **This example sends `end_date`.** Every shorter active rental is extended to that timestamp. Omit `end_date` if you only want to change price or SLA terms. ```bash curl -s -X PUT "https://console.vast.ai/api/v0/machines/create_asks/" \ @@ -831,9 +831,19 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ -d '{"sdate": START_UNIX_UTC, "duration": 2, "maintenance_category": "software"}' ``` -`sdate` is Unix epoch seconds (UTC). Use a future time, as far ahead as you can. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty, so do not rely on that field. Confirm the window with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)) or in the console under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). `--raw` is a JSON list. Each object includes `machine_id`, `start_time`, `end_time`, `duration_hours`, and `maintenance_category`. Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. Retries must not create a duplicate of the same one. If the work runs past the window, do not use `cancel maint` to lengthen it: that removes every window on the machine, and a new window starts its notice clock over. Remove one window with the console **✕**. See [Schedule Maintenance](/api-reference/machines/schedule-maint). + +`vastai cancel maint` removes **every** window on the machine. Do not use it to lengthen or move one window. In the console, **✕** cancels that one row. From the CLI, cancel all, then create again each window you still want. A new window starts its notice clock over. + + +**After you schedule** + +1. Confirm exactly one window for this downtime: `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)). A scoped key needs `instance_read` for that command. Or use **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). +2. `--raw` is a JSON list. Each object includes `machine_id`, `start_time` (Unix UTC), `end_time`, `duration_hours`, and `maintenance_category`. +3. Wait at least 3 seconds before the next machine. + +`sdate` is Unix epoch seconds (UTC). Use a future time. For an outage already underway, one minute from now is enough. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty. Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. In scripts, pass `--retry 1`. A retried PUT can create a second window if the first was stored and the response was lost. Confirm the count before you schedule the next machine. -**Cancel or reschedule:** [`vastai cancel maint`](/host/cli/cancel-maint) cancels **every** window you scheduled on that machine, not one window. It also asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the cancel succeeded before you schedule the replacement. Check with `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)), not only the console. In scripts, pass `--retry 1` on `schedule maint` and `cancel maint`. A retried PUT can create a second window if the first one was stored and the response was lost. Confirm exactly one window before you schedule the next machine. Otherwise a failed cancel plus a new window leaves duplicates. Maintenance windows that Vast scheduled are not cancelled. They stay listed as `admin_locked`. In the console, **✕** on a row cancels that one window. With the CLI or REST, `cancel maint` removes every window on the machine. To change one window from the CLI, cancel all of them, then create again each window you still want. A new window starts its notice clock over. Confirm under **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). +**Cancel or reschedule:** The command asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the list is empty of your windows before you schedule the replacement. Windows that Vast scheduled stay listed as `admin_locked` and are not cancelled. See [Schedule Maintenance](/api-reference/machines/schedule-maint). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -867,7 +877,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. - 6. Relist only if you unlisted in step 3. Relist **without** SLA first: leave the SLA controls closed, click **Save**, then **LIST**, and run `vastai self-test machine MACHINE_ID` (this needs the CLI; see [Self-test](/host/upgrade-docker-and-packages#self-test)). Re-enter the SLA terms and click **Save** only after the last line reads `Test completed successfully.` That second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. + 6. Relist only if you unlisted in step 3. Relist **without** SLA first: leave the SLA controls closed, click **Save**, then **LIST**, and run `vastai self-test machine MACHINE_ID` (this needs the CLI; see [Self-test](/host/upgrade-docker-and-packages#self-test)). Re-enter the SLA terms and click **Save** only after the last line reads `Test completed successfully.` If it will not start, leave SLA off. The test refuses a machine whose offer reliability is at or below 0.90, and it refuses a machine with no free GPU (`currently_rented` or `zero_active_offers`), which is normal while an SLA rental is still on it. Do not pass `--ignore-requirements` to turn SLA back on. That flag skips those checks. Contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID if you need SLA on before the test can run. That second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. **API** @@ -892,7 +902,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Relist without SLA, self-test, then turn SLA back on.** Relisting after an unlist creates a new ask, so stored values do not carry over. First send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. Run `vastai self-test machine MACHINE_ID`. Only after it passes, send a second `PUT /api/v0/machines/create_asks/` with the full body from [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body), not just the SLA fields: `price_disk`, `price_inetu`, `price_inetd`, `credit_discount_max`, `min_chunk`, `hidden_listing`, `"vol_size": 0`, plus `sla_r_claim` and `sla_sigma_x` from your notes. Omitting those listing fields resets them (`price_disk` goes back to $0.10, a hidden listing becomes public, and a missing `vol_size` can create a volume offer). On a fixed end date, omit `end_date` and `duration` on that second request so no rental is extended again. On a rolling listing, omitting `duration` turns auto-renew off. Resend the same integer `duration` if you want auto-renew to stay on. That duration is measured from now, so the second request can extend shorter rentals a bit further than the first. Sending a later `end_date` extends every active rental that ends sooner. No documented API shows each rental's end date. Check **Host → Machines** for the latest rental end date before you choose the `end_date` or `duration` on the first request. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Relist without SLA, self-test, then turn SLA back on.** Relisting after an unlist creates a new ask, so stored values do not carry over. First send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. Run `vastai self-test machine MACHINE_ID`. The same limits as the console step apply: if it will not start, leave SLA off. Only after it passes, send a second `PUT /api/v0/machines/create_asks/` with the full body from [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body), not just the SLA fields: `price_disk`, `price_inetu`, `price_inetd`, `credit_discount_max`, `min_chunk`, `hidden_listing`, `"vol_size": 0`, plus `sla_r_claim` and `sla_sigma_x` from your notes. Omitting those listing fields resets them (`price_disk` goes back to $0.10, a hidden listing becomes public, and a missing `vol_size` can create a volume offer). On a fixed end date, omit `end_date` and `duration` on that second request so no rental is extended again. On a rolling listing, omitting `duration` turns auto-renew off. Resend the same integer `duration` if you want auto-renew to stay on. That duration is measured from now, so the second request can extend shorter rentals a bit further than the first. Sending a later `end_date` extends every active rental that ends sooner. No documented API shows each rental's end date. Check **Host → Machines** for the latest rental end date before you choose the `end_date` or `duration` on the first request. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. ## Monitoring SLA after listing diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 495db183..47460213 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -21,7 +21,7 @@ vastai schedule maint id --sdate START_DATE --duration DURATION --maintenance_ca ## Options - Maintenance start time as Unix epoch seconds (UTC). Required. For planned work, use a future time, as far ahead as you can. For an outage already underway, one minute from now is enough. This single-machine route accepts the current time. + Maintenance start time as Unix epoch seconds (UTC). Required. For planned work, use a future time, as far ahead as you can. For an outage already underway, one minute from now is enough. From ad0df5e9d49e85c5f4c7bea625bda89881339fec Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 07:56:43 -0700 Subject: [PATCH 239/250] docs(sla): address doc-review consensus (cycle 183) The outage relist was one paragraph, and the billing page pointed renters at the wrong bullet. Co-authored-by: Cursor --- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 2 +- guides/reference/billing.mdx | 4 ++-- host/sla-offers.mdx | 25 ++++++++++++++++++---- host/upgrade-docker-and-packages.mdx | 6 ++++-- sdk/python/rate-limits.mdx | 2 +- 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 2b0d53e3..171c22b2 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -191,7 +191,7 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability`. The CLI cannot send it: a query string becomes `{"eq": …}` and returns HTTP 400, so CLI `--raw` output has no SLA fee. The Python SDK can, if you pass a dict such as `search_offers(query={"has_sla": {"eq": True}, "target_reliability": 0.95}, storage=50)`. Pass the same `storage` you will rent. The SDK default is 5 GiB, which changes `dph_total`. The SDK returns only the offers list. `truncated` is visible only via REST. A string query fails the same way as the CLI. `search_offers()` cannot rent with SLA. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. +**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability`. The CLI cannot send it: a query string becomes `{"eq": …}` and returns HTTP 400, so CLI `--raw` output has no SLA fee. The `VastAI` client can, if you pass a dict such as `search_offers(query={"has_sla": {"eq": True}, "target_reliability": 0.95}, storage=50)`. `SyncClient.search` (and `AsyncClient.search`) can also quote an SLA with `target_reliability` as a plain number. Neither client can enable SLA at rent: `create_instance()` and `InstanceConfig` have no `target_reliability`. `SyncClient` and `AsyncClient` do not retry. Pass the same `storage` you will rent. The SDK default is 5 GiB, which changes `dph_total`. The SDK returns only the offers list. `truncated` is visible only via REST. A string query fails the same way as the CLI. `search_offers()` cannot rent with SLA. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. | Field | Meaning | | --- | --- | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index d1525d64..31e624ee 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -367,7 +367,7 @@ Billing continues during downtime. You are still charged for **compute, storage, -During an outage the Instances price popover may say "Machine is offline. You're not being charged." That message does not apply to SLA rentals: compute, storage, and the SLA fee continue while the contract is active. +During an outage the Instances price popover may say "Machine is offline. You're not being charged." That message does not apply to SLA rentals: compute, storage, and the SLA fee continue while the contract is active. The **SLA Fee** line is hidden, and `slaPremiumPerHour` reads `0`, while an instance is stopped, loading, or offline. Neither means the charges have stopped. **This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index efac79aa..a81220b5 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -20,7 +20,7 @@ Once your credits reach \$0.00, your instances, storage volumes, and data **will **When your balance reaches zero (or below):** - Your instances are **stopped automatically**. On an SLA rental, see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). Top up, or **Destroy** the instance if you need charges to stop. Destroy deletes the disk. - - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. On an SLA rental, GPU and SLA fee charges may still continue while it is stopped (see the first bullet). If you have an SLA rental and no saved card, top up or **Destroy** the instance right away. Destroy deletes the disk. + - While an instance is stopped, your instance is detached from its GPU(s), but your data can still be copied off the machine. On an SLA rental, GPU and SLA fee charges may still continue while it is stopped (see [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage)). If you have an SLA rental and no saved card, top up or **Destroy** the instance right away. Destroy deletes the disk. - As with any stopped instance, **you will continue to be billed for disk storage**, even if your balance is negative. - To protect accounts with established usage history, **the system allows a short grace period where your balance may go negative before deletion occurs** -- the length of this buffer is calculated based on your account's average daily spend. Accounts with higher historical spend receive a proportionally larger buffer. @@ -50,7 +50,7 @@ We recommend: **WARNING** - Even stopped instances continue to accrue storage charges. When your balance drops to your autobilling threshold or goes negative, your card will automatically be charged. Destroy instances you no longer need to avoid being charged for idle resources. + Even stopped instances continue to accrue storage charges. On an SLA rental, GPU and SLA fee charges can also continue while the instance is stopped. **Destroy** the instance to end them. See [Stop vs destroy](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). When your balance drops to your autobilling threshold or goes negative, your card will automatically be charged. Destroy instances you no longer need to avoid being charged for idle resources. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 994bdcba..0c8923a4 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -25,7 +25,7 @@ SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. -Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong). Skip [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) and API automation unless you manage many machines with scripts. The console shows fleet-wide totals, with SLA folded into earnings. Per-machine SLA amounts need the CLI and an API key with `billing_read`. Outage recovery also needs the CLI: turning SLA back on requires `vastai self-test machine`. Install it before you enable SLA (checklist step 3). +Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong). Skip [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) and API automation unless you manage many machines with scripts. The console shows fleet-wide totals, with SLA folded into earnings. Per-machine SLA amounts need the CLI and an API key with `billing_read`. Outage recovery also needs the CLI. Do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` Nothing in the listing API checks that for you. Install the CLI before you enable SLA (checklist step 3). | Goal | Start here | @@ -42,7 +42,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. Turning SLA back on after an outage requires `vastai self-test machine`. You also need the CLI for maintenance from the command line and for per-machine SLA earnings. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. +3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. Do not turn SLA back on after an outage until `vastai self-test machine` prints `Test completed successfully.` The listing API does not check that for you. You also need the CLI for maintenance from the command line and for per-machine SLA earnings. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. @@ -877,7 +877,18 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. - 6. Relist only if you unlisted in step 3. Relist **without** SLA first: leave the SLA controls closed, click **Save**, then **LIST**, and run `vastai self-test machine MACHINE_ID` (this needs the CLI; see [Self-test](/host/upgrade-docker-and-packages#self-test)). Re-enter the SLA terms and click **Save** only after the last line reads `Test completed successfully.` If it will not start, leave SLA off. The test refuses a machine whose offer reliability is at or below 0.90, and it refuses a machine with no free GPU (`currently_rented` or `zero_active_offers`), which is normal while an SLA rental is still on it. Do not pass `--ignore-requirements` to turn SLA back on. That flag skips those checks. Contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID if you need SLA on before the test can run. That second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. **Host → Machines** shows the latest rental end date. Relisting before that date, with an end date after a shorter rental, extends that rental and its SLA exposure. To avoid any extension, wait until that date has passed, then relist. If you relist sooner, assume shorter rentals will be extended. + 6. **Return to service** only if you unlisted in step 3. + + a. **Decide when to relist.** **Host → Machines** shows the latest rental end date. Any **Save** that sends a later end date extends shorter rentals. To avoid that, wait until the date has passed. If you relist sooner, assume shorter rentals will be extended. + + b. **Relist without SLA.** In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. + + c. **Run the self-test** (`vastai self-test machine MACHINE_ID`; see [Self-test](/host/upgrade-docker-and-packages#self-test)). + - Last line is `Test completed successfully.` Go to step d. + - It refuses to start (`currently_rented`, `zero_active_offers`, or offer reliability at or below 0.90). Stay listed without SLA and try again later. Do not pass `--ignore-requirements`. That flag skips those checks. Contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID if you need SLA on before the test can run. + - It runs and fails a check. Unlist, then fix the machine using [How to self-test](/host/how-to-self-test). + + d. **Re-enable SLA.** Re-enter the SLA terms and click **Save**. This second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. Check the date in step a before you click it. **API** @@ -902,7 +913,13 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. - 6. **Relist without SLA, self-test, then turn SLA back on.** Relisting after an unlist creates a new ask, so stored values do not carry over. First send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. Run `vastai self-test machine MACHINE_ID`. The same limits as the console step apply: if it will not start, leave SLA off. Only after it passes, send a second `PUT /api/v0/machines/create_asks/` with the full body from [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body), not just the SLA fields: `price_disk`, `price_inetu`, `price_inetd`, `credit_discount_max`, `min_chunk`, `hidden_listing`, `"vol_size": 0`, plus `sla_r_claim` and `sla_sigma_x` from your notes. Omitting those listing fields resets them (`price_disk` goes back to $0.10, a hidden listing becomes public, and a missing `vol_size` can create a volume offer). On a fixed end date, omit `end_date` and `duration` on that second request so no rental is extended again. On a rolling listing, omitting `duration` turns auto-renew off. Resend the same integer `duration` if you want auto-renew to stay on. That duration is measured from now, so the second request can extend shorter rentals a bit further than the first. Sending a later `end_date` extends every active rental that ends sooner. No documented API shows each rental's end date. Check **Host → Machines** for the latest rental end date before you choose the `end_date` or `duration` on the first request. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + 6. **Return to service.** + + a. **First PUT, without SLA.** Relisting creates a new ask, so stored values do not carry over. Send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. No documented API shows each rental's end date. Check **Host → Machines** before you choose `end_date` or `duration`. Sending either extends every active rental that ends sooner. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. + + b. **Self-test.** Run `vastai self-test machine MACHINE_ID`. Use the same three outcomes as the console step: pass, refuses to start, or fails a check. If it will not start, leave SLA off. + + c. **Second PUT, with SLA.** Only after the last line is `Test completed successfully.`, send the full body from [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body): `price_disk`, `price_inetu`, `price_inetd`, `credit_discount_max`, `min_chunk`, `hidden_listing`, `"vol_size": 0`, plus `sla_r_claim` and `sla_sigma_x` from your notes. Omitting those listing fields resets them (`price_disk` goes back to $0.10, a hidden listing becomes public, and a missing `vol_size` can create a volume offer). On a fixed end date, omit `end_date` and `duration` so no rental is extended again. On a rolling listing, omitting `duration` turns auto-renew off. Resend the same integer `duration` if you want auto-renew to stay on. That duration is measured from now, so this second request can extend shorter rentals a bit further than the first. ## Monitoring SLA after listing diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index 3a2e5162..891b4e45 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -562,8 +562,10 @@ vastai self-test machine Test completed successfully. ``` -The last line must be `Test completed successfully.`. On failure the output -names the failing check; see [How to self-test](/host/how-to-self-test). If it fails and you already relisted an SLA machine, unlist it. +The last line must be `Test completed successfully.` + +- **It refuses to start** (offer reliability at or below 0.90, `currently_rented`, or `zero_active_offers`): stay listed without SLA and run it again later. Do not pass `--ignore-requirements` to turn SLA back on. +- **It runs and fails a check:** the output names the check. See [How to self-test](/host/how-to-self-test). If you already relisted an SLA machine, unlist it. New Docker, containerd and driver; every GPU visible on the host and in a diff --git a/sdk/python/rate-limits.mdx b/sdk/python/rate-limits.mdx index 73f094f3..56a55baf 100644 --- a/sdk/python/rate-limits.mdx +++ b/sdk/python/rate-limits.mdx @@ -42,7 +42,7 @@ The SDK never reads `Retry-After`. With the default of 3 attempts, its retries f ## Built-in Retry Behavior -The SDK includes two clients with different retry strategies. +The `VastAI` client and the serverless client retry. `SyncClient` and `AsyncClient` call the API directly and do not retry, so add your own backoff. ### VastAI Client From 8d37ab425813c18162c431bbb4d595fc00dab377 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 08:05:04 -0700 Subject: [PATCH 240/250] docs(sla): address doc-review consensus (cycle 184) The post-outage self-test stays blocked until the current rental ends, and show machines left out the fields those scripts read. Co-authored-by: Cursor --- api-reference/openapi.yaml | 31 +++++++++++++++++-- api-reference/openapi/yaml/show_machines.yaml | 24 ++++++++++++-- cli/reference/create-instance.mdx | 2 +- host/sla-backtester.mdx | 4 +-- host/sla-offers.mdx | 14 ++++----- host/upgrade-docker-and-packages.mdx | 2 +- sdk/python/reference/create-instance.mdx | 2 +- 7 files changed, 63 insertions(+), 16 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 35a72e2e..83650417 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9073,6 +9073,15 @@ paths: description: Ignored. Results are scoped to the API key owner. schema: type: string + - name: include_offline + in: query + required: false + schema: + type: boolean + description: 'When true, include this host''s machines that have been offline + for up to about 3 days. The default cutoff is about 10 hours. + + ' responses: '200': description: A list of machines @@ -9087,7 +9096,7 @@ paths: type: object properties: id: - type: string + type: integer description: The unique identifier for the machine. name: type: string @@ -9165,9 +9174,27 @@ paths: null otherwise. `low` is Wide, not low risk. ' + current_rentals_resident: + type: + - integer + - 'null' + description: Resident rentals on the machine, including + stopped ones. Null when the summary is missing. + credit_discount_max: + type: + - number + - 'null' + description: Reserved discount on the ask. Null when the + machine is not listed. + min_bid_price: + type: + - number + - 'null' + description: Host-side minimum bid, net of the platform + fee. It does not round-trip as price_min_bid. example: machines: - - id: '12345' + - id: 12345 name: my-h100 listed: true listed_gpu_cost: 3.5 diff --git a/api-reference/openapi/yaml/show_machines.yaml b/api-reference/openapi/yaml/show_machines.yaml index 90403bc2..50d4bba3 100644 --- a/api-reference/openapi/yaml/show_machines.yaml +++ b/api-reference/openapi/yaml/show_machines.yaml @@ -20,6 +20,14 @@ paths: description: Ignored. Results are scoped to the API key owner. schema: type: string + - name: include_offline + in: query + required: false + schema: + type: boolean + description: > + When true, include this host's machines that have been offline for up to about 3 days. + The default cutoff is about 10 hours. responses: '200': description: A list of machines @@ -34,7 +42,7 @@ paths: type: object properties: id: - type: string + type: integer description: The unique identifier for the machine. name: type: string @@ -82,9 +90,21 @@ paths: description: | Confidence band for the ask's `sla_sigma_x`: high = Tight (sigma_x <= 0.32), medium = Normal (<= 0.71), low = Wide. Same visibility as `sla_reliability_claim`: present when terms are visible, null otherwise. `low` is Wide, not low risk. + current_rentals_resident: + type: integer + nullable: true + description: Resident rentals on the machine, including stopped ones. Null when the summary is missing. + credit_discount_max: + type: number + nullable: true + description: Reserved discount on the ask. Null when the machine is not listed. + min_bid_price: + type: number + nullable: true + description: Host-side minimum bid, net of the platform fee. It does not round-trip as price_min_bid. example: machines: - - id: "12345" + - id: 12345 name: my-h100 listed: true listed_gpu_cost: 3.5 diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index a7e0493d..62313461 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -11,7 +11,7 @@ Create a new instance **SLA** - This command cannot set `target_reliability`. -- No **SLA Fee** line on the Search offer, or on a **running** instance, means you do **not** have an SLA (even if search quoted SLA). The line is hidden while the instance is loading, stopped, or offline. +- No **SLA Fee** line on the Search offer, or on a **running** instance, means you do **not** have an SLA, even if an earlier CLI or REST search returned SLA pricing. The line is hidden while the instance is loading, stopped, or offline. - Enable SLA in the console: **Search filters** (left bar) → **Reliability target**, confirm **SLA fee**, then **RENT**—or REST `PUT /api/v0/asks/{id}/` with `target_reliability`. - See [SLA coverage](/guides/instances/choosing/sla-coverage#finding-sla-offers). Match `--disk` to any `--storage` you used in search. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 51133ed7..c2aa3974 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -136,7 +136,7 @@ Compare two confidence levels on the same history: curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.6667" -# Low (p=0.50): recommended start for a new or low-history machine. +# p=0.50 (Low): recommended starting confidence when you first enable SLA. A machine with no rental history returns has_data false. # Renters pay a higher SLA fee. Credit rules are the same. curl -s -H "Authorization: Bearer YOUR_API_KEY" \ "https://console.vast.ai/api/v0/host/sla_backtest/?machine_id=12345&r_claim=0.99&p=0.50" @@ -274,7 +274,7 @@ Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** ## Recommended workflow -1. **Run a baseline** on a machine with at least a few weeks of rental history, with `r_claim` set to the commitment you plan to list and `p=0.6667` (Medium). For a new machine, also run `p=0.50` (Low), the recommended starting confidence. If `has_data` is `false`, move the date range toward the present or wait for more history. Don't rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). +1. **Run a baseline** on a machine with at least a few weeks of rental history, with `r_claim` set to the commitment you plan to list and `p=0.6667` (Medium). If this machine already has rental history and you are about to enable SLA, also run `p=0.50` (Low), the recommended starting confidence. A machine with no rental history returns `has_data: false`. There is nothing to replay. If `has_data` is `false` on a machine that has been rented, move the date range toward the present. Don't rely on the dashboard reliability score alone (see [Machine reliability score vs SLA reliability](/host/sla-offers#machine-reliability-score-vs-sla-reliability)). 2. **Compare `r_eff` with `r_be`** to see whether you had headroom. 3. **Add `r_target`** at the targets renters are likely to choose (for example `0.95`) and compare `net_sla`. 4. **Check `largest_day_credit`** — can you absorb that from one bad day? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 0c8923a4..2139f0ed 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -48,7 +48,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. - **All hosts:** After you enable SLA, GPU earnings in **Host → Billing** can drop. That compute is paid out later as SLA earnings, and much of it can stay held until the contract ends. A lower total is not by itself a credit. - **API users:** Read the held amount as `sla_earn`. See [Monitoring SLA after listing](#monitoring-sla-after-listing). -6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Host → Notification Settings** for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. +6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Account Settings → Notification Settings** (Host group) for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. **Enable SLA.** - **Do this:** In **Set Pricing → SLA**, enter **Reliability Commitment** as a percent (the field ends with `%`; type `99` for 99%). Set **Confidence**. Start at **Low** unless you have rental history. Then click **Save**. - **What Save also does:** On a machine that is already listed, **Save** publishes immediately and extends every shorter rental to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). @@ -152,7 +152,7 @@ On sliced machines, SLA settles **per rental contract**. If one GPU slice fails For SLA-covered on-demand contracts, the renter is still charged the normal hourly rate during an outage. Vast does not zero that day's compute bill. Compensation is a service credit. -**Where SLA money goes.** On an SLA rental, the renter's compute payment and SLA fee are held by Vast (escrow) instead of being paid to you right away. Service credits are paid from that held money, and the rest is released to you over the following days. Those earnings show up as **SLA** earnings (`sla_earn`), not GPU earnings. See [How SLA money moves](/host/sla-backtester#how-sla-money-moves). +**Where SLA money goes.** On an SLA rental, the renter's compute payment and SLA fee are held by Vast (escrow) instead of being paid to you right away. Service credits are paid from that held money, and the rest is released over time. Some of it can stay held until the contract ends. Those earnings show up as **SLA** earnings (`sla_earn`), not GPU earnings. See [How SLA money moves](/host/sla-backtester#how-sla-money-moves). ## SLA parameters @@ -413,7 +413,7 @@ Then `PUT /api/v0/machines/create_asks/` with the merged body (read → merge ### Fleet SLA re-list (machines that already have an SLA) -Use this loop only to restore SLA offers that no longer appear in search on machines with **zero** rentals. It does not change prices or SLA terms. To change terms, use [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). `current_rentals_resident`, `credit_discount_max`, and `min_bid_price` are on `GET /api/v0/machines/` but are not all in the Show Machines OpenAPI schema yet. A typed client that drops `current_rentals_resident` will skip every machine. +Use this loop only to restore SLA offers that no longer appear in search on machines with **zero** rentals. It does not change prices or SLA terms. To change terms, use [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body). `current_rentals_resident`, `credit_discount_max`, and `min_bid_price` are on `GET /api/v0/machines/` and in the Show Machines schema. A client that drops `current_rentals_resident` will skip every machine. "Missing from search" also matches every **hidden** listing (hidden listings are not shown in search) and every **offline** machine (`create_asks` returns HTTP 402 until the machine is online). Any hidden machine not listed in `HIDDEN_IDS` becomes **public** on a live run. The loop skips machines in `HIDDEN_IDS` unless you set `RELIST_HIDDEN=1`. Set `HIDDEN_IDS` before `DRY_RUN=0` (space-separated IDs, or `HIDDEN_IDS=none` if you have no hidden listings). @@ -884,9 +884,9 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep b. **Relist without SLA.** In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. c. **Run the self-test** (`vastai self-test machine MACHINE_ID`; see [Self-test](/host/upgrade-docker-and-packages#self-test)). - - Last line is `Test completed successfully.` Go to step d. - - It refuses to start (`currently_rented`, `zero_active_offers`, or offer reliability at or below 0.90). Stay listed without SLA and try again later. Do not pass `--ignore-requirements`. That flag skips those checks. Contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID if you need SLA on before the test can run. - - It runs and fails a check. Unlist, then fix the machine using [How to self-test](/host/how-to-self-test). + - **If the last line is `Test completed successfully.`**, go to step d. + - **If it refuses to start** (`currently_rented`, `zero_active_offers`, or offer reliability at or below 0.90), stay listed without SLA. `currently_rented` stays until that rental ends. A **Save** that just extended it can push the end date out by days or weeks, and a machine listed without SLA can be rented again before you test. Do not pass `--ignore-requirements`. That flag skips these checks. If you need SLA on before the test can run, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID. + - **If it runs and fails a check**, unlist, fix the machine using [How to self-test](/host/how-to-self-test), and repeat from step a. d. **Re-enable SLA.** Re-enter the SLA terms and click **Save**. This second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. Check the date in step a before you click it. @@ -917,7 +917,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep a. **First PUT, without SLA.** Relisting creates a new ask, so stored values do not carry over. Send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. No documented API shows each rental's end date. Check **Host → Machines** before you choose `end_date` or `duration`. Sending either extends every active rental that ends sooner. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. - b. **Self-test.** Run `vastai self-test machine MACHINE_ID`. Use the same three outcomes as the console step: pass, refuses to start, or fails a check. If it will not start, leave SLA off. + b. **Self-test.** Run `vastai self-test machine MACHINE_ID`. Use the same three outcomes as the console step. If it refuses to start, leave SLA off until the rental ends or the reliability score recovers. That wait can last as long as the extended contract. c. **Second PUT, with SLA.** Only after the last line is `Test completed successfully.`, send the full body from [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body): `price_disk`, `price_inetu`, `price_inetd`, `credit_discount_max`, `min_chunk`, `hidden_listing`, `"vol_size": 0`, plus `sla_r_claim` and `sla_sigma_x` from your notes. Omitting those listing fields resets them (`price_disk` goes back to $0.10, a hidden listing becomes public, and a missing `vol_size` can create a volume offer). On a fixed end date, omit `end_date` and `duration` so no rental is extended again. On a rolling listing, omitting `duration` turns auto-renew off. Resend the same integer `duration` if you want auto-renew to stay on. That duration is measured from now, so this second request can extend shorter rentals a bit further than the first. diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index 891b4e45..b590c366 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -564,7 +564,7 @@ Test completed successfully. The last line must be `Test completed successfully.` -- **It refuses to start** (offer reliability at or below 0.90, `currently_rented`, or `zero_active_offers`): stay listed without SLA and run it again later. Do not pass `--ignore-requirements` to turn SLA back on. +- **If it refuses to start** (offer reliability at or below 0.90, `currently_rented`, or `zero_active_offers`): stay listed without SLA. `currently_rented` clears when that rental ends, which can be a long time if the contract was just extended. Do not pass `--ignore-requirements` to turn SLA back on. - **It runs and fails a check:** the output names the check. See [How to self-test](/host/how-to-self-test). If you already relisted an SLA machine, unlist it. diff --git a/sdk/python/reference/create-instance.mdx b/sdk/python/reference/create-instance.mdx index 9284be5f..9b9f9253 100644 --- a/sdk/python/reference/create-instance.mdx +++ b/sdk/python/reference/create-instance.mdx @@ -6,7 +6,7 @@ sidebarTitle: "create_instance" Create a new instance from an offer/ask ID returned by search. -**SLA:** `target_reliability` is not available on `create_instance()` today. No **SLA Fee** line on the Search offer, or on a **running** instance, means you do **not** have an SLA—even if search showed SLA pricing. The line is hidden while the instance is loading, stopped, or offline. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). +**SLA:** `target_reliability` is not available on `create_instance()` today. No **SLA Fee** line on the Search offer, or on a **running** instance, means you do **not** have an SLA, even if an earlier search returned SLA pricing. The line is hidden while the instance is loading, stopped, or offline. Use the web console or REST `PUT /api/v0/asks/{id}/` to enable the SLA — see [SLA](/guides/instances/choosing/sla-coverage#api-automation). Use the same storage number in search (`allocated_storage` or `--storage`) and in the rent body (`disk`). ## Signature From 2d9118d221b6fc315e9fb2cd81a26f30452a8fd8 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 08:13:30 -0700 Subject: [PATCH 241/250] docs(sla): address doc-review consensus (cycle 185) show maints labels Vast-scheduled windows as admin_scheduled, and unlisting during an outage can leave SLA off until the rental ends. Co-authored-by: Cursor --- guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/hosting-overview.mdx | 4 ++-- host/sla-offers.mdx | 16 ++++++++-------- snippets/host/cli/show-maints.mdx | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 0bbe5ce4..05f40430 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -87,7 +87,7 @@ Click on the "Change Template" button to bring up the template config menu that ![Edit](/images/find-and-rent-edit.webp) -Some offers include an optional **SLA** reliability guarantee. To filter and compare SLA-backed rentals, see [SLA](/guides/instances/choosing/sla-coverage). +Some offers include an optional **SLA** reliability commitment. It pays a service credit when uptime falls short. It does not keep the machine up. To filter and compare SLA-backed rentals, see [SLA](/guides/instances/choosing/sla-coverage). ## Common Questions diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 31e624ee..323d74c0 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -72,7 +72,7 @@ You do not post escrow or collateral for SLA. You pay the SLA fee while your ren ## What SLA protects -SLA is a **contractual, per-rental** reliability guarantee with automatic daily settlement. It is **not** the same as verification or the **reliability score** on offer cards — those are platform trust signals (see [Machine Tiers](/guides/instances/choosing/find-and-rent#machine-tiers)). +SLA is a **contractual, per-rental** reliability commitment with automatic daily settlement, paid as service credits. It does not keep the machine up. It is **not** the same as verification or the **reliability score** on offer cards — those are platform trust signals (see [Machine Tiers](/guides/instances/choosing/find-and-rent#machine-tiers)). For on-demand contracts with an SLA: @@ -489,7 +489,7 @@ No. The target is fixed when the contract is created. **Destroy** the instance ( ### Does SLA replace verification? -No. Verification is a platform quality signal (see [Machine Tiers](/guides/instances/choosing/find-and-rent#machine-tiers)). SLA is a financial guarantee on a specific contract. +No. Verification is a platform quality signal (see [Machine Tiers](/guides/instances/choosing/find-and-rent#machine-tiers)). SLA is a service-credit commitment on a specific contract, not a promise the machine stays up. ### Where do I see historical SLA credits? diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index b0b7a880..a54a178c 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -8,7 +8,7 @@ description: "Set up hosting on Vast.ai: accounts, machines, offers, maintenance **Looking to rent GPUs?** See [Finding & Renting Instances](/guides/instances/choosing/find-and-rent) and [SLA](/guides/instances/choosing/sla-coverage). -**Offering an SLA?** Optional on-demand uptime guarantee—read economics and risk before you enable it. Start with the [SLA host checklist](/host/sla-offers#sla-host-checklist) and [Before you enable SLA](/host/sla-offers#before-you-enable-sla). +**Offering an SLA?** Optional reliability commitment, paid as service credits, not guaranteed uptime. Read economics and risk before you enable it. Start with the [SLA host checklist](/host/sla-offers#sla-host-checklist) and [Before you enable SLA](/host/sla-offers#before-you-enable-sla). Vast is a GPU marketplace. Hosts sell GPU resources on the marketplace. Hosts are responsible for: @@ -51,7 +51,7 @@ The main offer parameters include: - the min bid price for [interruptible](/guides/instances/rental-types) instances - the min_gpu param controlling 'slicing' (explained below) — same concept as CLI `min_chunk` / `-m` - the offer end date, which determines how long the offer accepts new rental contracts -- **SLA (optional):** On-demand uptime guarantee; configure under **Set Pricing → SLA**. Start here: [SLA host checklist](/host/sla-offers#sla-host-checklist). Renters: [SLA](/guides/instances/choosing/sla-coverage). +- **SLA (optional):** Reliability commitment paid as service credits, not guaranteed uptime. Configure under **Set Pricing → SLA**. Start here: [SLA host checklist](/host/sla-offers#sla-host-checklist). Renters: [SLA](/guides/instances/choosing/sla-coverage). The offer accepts new rentals until the offer end date. When a client rents an instance on your machine, a rental contract is created from your offer. If your machine has multiple GPUs and you've set min_gpu to allow slicing, multiple clients can rent from the same offer, each creating their own independent rental contract. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 2139f0ed..84511d47 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -4,7 +4,7 @@ description: "Offer an SLA on your machines: set a reliability commitment and co "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability guarantee: clients who choose an SLA pay a small hourly **SLA fee** included in **`dph_total`** (dollars per hour total in search — GPU + storage + SLA fee), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability commitment, paid as daily service credits, not as guaranteed uptime: clients who choose an SLA pay a small hourly **SLA fee** included in **`dph_total`** (dollars per hour total in search — GPU + storage + SLA fee), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. The **SLA fee** is that hourly amount. It appears as the **SLA Fee** line in the console. API field names call the same amount a premium (for example `slaPremiumPerHour`). @@ -24,8 +24,8 @@ SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. - -Use [Web console](#web-console) and [When things go wrong](#when-things-go-wrong). Skip [Fleet SLA re-list](#fleet-sla-re-list-machines-that-already-have-an-sla) and API automation unless you manage many machines with scripts. The console shows fleet-wide totals, with SLA folded into earnings. Per-machine SLA amounts need the CLI and an API key with `billing_read`. Outage recovery also needs the CLI. Do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` Nothing in the listing API checks that for you. Install the CLI before you enable SLA (checklist step 3). + +You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. If you stayed listed, your SLA terms did not change and there is nothing to turn back on. A full-access key covers this page. A scoped key needs `billing_read`, `machine_read`, `machine_write`, `instance_read`, and `misc` for the offer search the self-test runs. See the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). | Goal | Start here | @@ -42,7 +42,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. Do not turn SLA back on after an outage until `vastai self-test machine` prints `Test completed successfully.` The listing API does not check that for you. You also need the CLI for maintenance from the command line and for per-machine SLA earnings. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. +3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. If you unlisted during an outage, do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` The listing API does not check that for you. If you stayed listed, your SLA terms did not change. You also need the CLI for maintenance from the command line and for per-machine SLA earnings. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. @@ -838,12 +838,12 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ **After you schedule** 1. Confirm exactly one window for this downtime: `vastai show maints --ids 'MACHINE_ID' --raw` ([show maints](/host/cli/show-maints)). A scoped key needs `instance_read` for that command. Or use **Machine Maintenances** (redesigned page) or **Scheduled Maintenances** (classic page). -2. `--raw` is a JSON list. Each object includes `machine_id`, `start_time` (Unix UTC), `end_time`, `duration_hours`, and `maintenance_category`. +2. `--raw` is a JSON list. Each object includes `machine_id`, `start_time` (Unix UTC), `end_time`, `duration_hours`, `maintenance_category`, and `admin_scheduled` (`true` when Vast scheduled that window). 3. Wait at least 3 seconds before the next machine. `sdate` is Unix epoch seconds (UTC). Use a future time. For an outage already underway, one minute from now is enough. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty. Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. In scripts, pass `--retry 1`. A retried PUT can create a second window if the first was stored and the response was lost. Confirm the count before you schedule the next machine. -**Cancel or reschedule:** The command asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the list is empty of your windows before you schedule the replacement. Windows that Vast scheduled stay listed as `admin_locked` and are not cancelled. See [Schedule Maintenance](/api-reference/machines/schedule-maint). +**Cancel or reschedule:** The command asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the list is empty of your windows before you schedule the replacement. `cancel maint` does not cancel windows that Vast scheduled. In `show maints --raw` those rows have `admin_scheduled: true`. The cancel response reports how many it left in place as `admin_locked` (a count). See [Schedule Maintenance](/api-reference/machines/schedule-maint). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -874,7 +874,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Console** 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). Change **Maintenance start** to a few minutes from now. The form starts 24 hours ahead. An emergency window is still unplanned, so expect full SLA exposure for it. 2. Write down every field on **Set Pricing**: GPU price, minimum GPUs, storage price, bandwidth, reserved discount, min bid, whether the listing is **hidden**, the offer end date or auto-renew duration, **Reliability Commitment**, and **Confidence**. If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. - 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. + 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. If a rental is still on the machine, SLA stays off for new rentals until that rental ends: the self-test refuses with `currently_rented`, and the relist **Save** can extend the rental. If the machine cannot take new rentals, staying listed keeps your SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. 6. **Return to service** only if you unlisted in step 3. @@ -910,7 +910,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep ``` `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). If that `include_offline` response is also empty, use the console notes above. Do not unlist until you have the terms. - 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. + 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. If a rental is still on the machine, SLA stays off for new rentals until that rental ends, because the self-test refuses with `currently_rented`. Staying listed keeps the current SLA terms. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. 6. **Return to service.** diff --git a/snippets/host/cli/show-maints.mdx b/snippets/host/cli/show-maints.mdx index d687eca4..491add21 100644 --- a/snippets/host/cli/show-maints.mdx +++ b/snippets/host/cli/show-maints.mdx @@ -25,7 +25,7 @@ vastai show maints --ids 'machine_id_1,machine_id_2' [OPTIONS] vastai show maints --ids '12345,12346' --raw ``` -`--raw` prints a JSON list, one object per window. Each object includes `machine_id`, `start_time` (Unix seconds, UTC), `end_time`, `duration_hours`, and `maintenance_category`. To count windows that start at one time: +`--raw` prints a JSON list, one object per window. Each object includes `machine_id`, `start_time` (Unix seconds, UTC), `end_time`, `duration_hours`, `maintenance_category`, and `admin_scheduled` (`true` when Vast scheduled that window). To count windows that start at one time: ```bash vastai show maints --ids '12345' --raw | jq --argjson s 1784851200 '[.[] | select(.start_time == $s)] | length' From 810175a18f140fb9d9be49a0a7577f05aabaf883 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 08:26:46 -0700 Subject: [PATCH 242/250] docs(sla): address doc-review consensus (cycle 186) Meeting the SLA target is not a zero-credit day. Settlement still pays about half of that day's covered compute. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 8 +++--- guides/reference/billing.mdx | 2 +- guides/reference/faq/billing.mdx | 2 +- host/sla-offers.mdx | 31 ++++++++++++---------- host/upgrade-docker-and-packages.mdx | 2 +- snippets/host/cli/list-machine.mdx | 2 +- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 323d74c0..1bf23186 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -399,14 +399,14 @@ Using the H100 example ($84/day compute, ~$0.97/day SLA fee, target 95%, host re | Scenario | Approx. SLA fee | Approx. service credit | Credit minus SLA fee | | --- | --- | --- | --- | -| Above target (excellent / good day) | ~$0.97/day | $0 | **−$0.97** (you paid the SLA fee) | -| Short outage that still meets the target (about 1 hour offline) | ~$0.97/day | $0 | **−$0.97**, plus about $3.50 of GPU billed for that hour (a non-SLA rental is not billed for it) | -| Below target (~93–94% for the day) | ~$0.97/day | ~$42 | **+$41** (credit after the SLA fee) | +| Well above the target | ~$0.97/day | Small | You can still pay more than the SLA fee | +| About the target | ~$0.97/day | About half of that day's covered compute | On the order of **+$41** in this example | +| Short outage (about 1 hour) | ~$0.97/day | Not zero if the day is near the target | Plus about $3.50 of GPU billed for that hour | | Severe shortfall (~90% or less) | ~$0.97/day | ~$84 | **+$83** | These rows assume the shortfall lasts long enough that the blended measure is that low. A single bad day after several good days usually pays less than the row, because the good days are still in the blend. -**How to read “Credit minus SLA fee”:** this column is only the service credit minus the SLA fee. It is not your net versus a non-SLA rental. On an SLA rental, offline time is still billed as GPU compute, storage, and the SLA fee. On a non-SLA rental it is not, so add that billed downtime when you compare the two. Credits grow with the size of the shortfall. In this example, a day 1–2 points below target pays a meaningful share of that day's compute, not a token amount. Figures are illustrative. A day where the **blended measure** meets your target does not pay a credit. Raw daily uptime can sit at or slightly above the target while the blended measure is still below it. +**How to read “Credit minus SLA fee”:** this column is only the service credit minus the SLA fee. It is not your net versus a non-SLA rental. On an SLA rental, offline time is still billed as GPU compute, storage, and the SLA fee. On a non-SLA rental it is not, so add that billed downtime when you compare the two. Credits grow with the size of the shortfall. Settlement is a smooth curve, not pass/fail. A day at your target still pays a credit of about half of that day's covered compute. A day a point or two below pays more. Figures are illustrative. Raw daily uptime and the blended measure are not the same number. Production settlement can issue credits even when a single daily snapshot looks close to your target, because measurement uses the blended daily reliability calculation. diff --git a/guides/reference/billing.mdx b/guides/reference/billing.mdx index a81220b5..f64fe9c1 100644 --- a/guides/reference/billing.mdx +++ b/guides/reference/billing.mdx @@ -83,7 +83,7 @@ You are charged the base active rental cost for every second your instance is in You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. Exception: on an SLA rental, budget as if GPU compute, storage, and the SLA fee continue while the instance is offline, stopped, or loading. **Destroy** is the reliable way to end those charges. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are not charged active rental or storage costs for instances that are currently offline. Exception: on an SLA rental, GPU compute, storage, and the SLA fee continue while the instance is offline. For **Stopped** and **Loading**, budget as if those charges continue too. **Destroy** is the reliable way to end them. A service credit can still be paid on a day that meets the target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). To see a pricing breakdown on your current instances within your Instance page in the console or from offers on the Search page you can hover over the price to see pricing details. diff --git a/guides/reference/faq/billing.mdx b/guides/reference/faq/billing.mdx index 9fa69e06..bff3df95 100644 --- a/guides/reference/faq/billing.mdx +++ b/guides/reference/faq/billing.mdx @@ -33,7 +33,7 @@ You are charged the storage cost (which depends on the size of your storage allo Stopping an instance does not avoid storage costs. You are charged bandwidth prices for every byte sent or received to or from the instance, regardless of what state it is in. The prices for base rental, storage, and bandwidth vary considerably from machine to machine, so make sure to check them. -You are not charged active rental or storage costs for instances that are currently offline. Exception: on an SLA rental, budget as if GPU compute, storage, and the SLA fee continue while the instance is offline, stopped, or loading. **Destroy** is the reliable way to end those charges. You may receive a service credit only if measured reliability falls below your reliability target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). +You are not charged active rental or storage costs for instances that are currently offline. Exception: on an SLA rental, GPU compute, storage, and the SLA fee continue while the instance is offline. For **Stopped** and **Loading**, budget as if those charges continue too. **Destroy** is the reliable way to end them. A service credit can still be paid on a day that meets the target. See [SLA coverage](/guides/instances/choosing/sla-coverage#what-you-pay-during-an-outage). ### What is the billing frequency? diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 84511d47..946b654b 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -25,7 +25,7 @@ SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. -You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. If you stayed listed, your SLA terms did not change and there is nothing to turn back on. A full-access key covers this page. A scoped key needs `billing_read`, `machine_read`, `machine_write`, `instance_read`, and `misc` for the offer search the self-test runs. See the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). +You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. Outage recovery, including when to turn SLA back on, is in [Severe outage](#severe-outage). A full-access key covers this page. A scoped key needs `billing_read`, `machine_read`, `machine_write`, `instance_read`, and `misc` for the offer search the self-test runs. See the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). | Goal | Start here | @@ -42,7 +42,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. If you unlisted during an outage, do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` The listing API does not check that for you. If you stayed listed, your SLA terms did not change. You also need the CLI for maintenance from the command line and for per-machine SLA earnings. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. +3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. You need it for per-machine SLA earnings and, if you later unlist during an outage, for `vastai self-test machine`. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. Outage recovery is in [Severe outage](#severe-outage), not in this checklist. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. @@ -99,7 +99,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. If it met the renter's target, you keep the SLA fee and no credit is paid. If it fell short, the renter receives a **service credit** from your earnings. Vast holds SLA rental pay and releases it over time, so a low earnings day is not by itself a credit. Details are in [Billing vs settlement](#billing-vs-settlement-important). +6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. Settlement is a smooth curve around the renter's target, not a pass/fail line. Well above the target, the credit is small but can still exceed that day's SLA fee. At the target, the credit is about half of that day's covered compute. Further below, it approaches a full day of covered compute. The renter's **service credit** comes from your earnings. Vast holds SLA rental pay and releases it over time, so a low earnings day is not by itself a credit. Details are in [Billing vs settlement](#billing-vs-settlement-important). 7. One bad day can cost more than many days of fees. What this is not: @@ -310,7 +310,7 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons #### Update SLA on an existing ask (partial body) -**Not a first listing.** Use this SLA-only body when the machine already has base pricing. For a **first publish**, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include at least `min_chunk`, disk/bandwidth prices, and `end_date`) or **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). +**Not a first listing.** Use this SLA-only body when the machine already has base pricing. For a **first publish**, or a relist after unlist, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include `price_gpu`, `min_chunk`, disk and bandwidth prices, and `end_date`). A new ask without `price_gpu` returns HTTP 400. or **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). Some omitted fields reset to defaults (for example `price_disk`, `hidden_listing`, and `duration`). Read the warning under [Full listing update](#full-listing-update-existing-ask) before you copy a body. `"vol_size": 0` keeps a new volume offer from being created. It does not delete a volume offer you already have. @@ -742,12 +742,12 @@ In the **You net** column, values follow host earnings sign conventions: positiv | Blended reliability vs the client's target | You net (per day) | | --- | --- | -| Meets or exceeds the target (for example blended ~99% vs a 95% target) | +$0.97 (keep the full SLA fee) | +| Well above the target (for example blended ~99% vs a 95% target) | A small credit, which can still exceed that day's SLA fee | -When the blended measure meets the target, you keep the SLA fee. These rows are not raw uptime. +These rows are not raw uptime. Meeting the target does not mean the credit is zero. -Settlement uses a **blended** reliability measure (recent plus longer-term uptime), not the day's raw uptime alone. A day whose raw uptime is at or slightly above the target can still settle with a small partial credit if the blended measure falls below it. When the blended measure meets the target, no credit is paid. +Settlement uses a **blended** reliability measure (recent plus longer-term uptime), not the day's raw uptime alone. Raw uptime and the blended measure are not the same number. A day at the target still settles with a credit of about half of that day's covered compute. ### What if measured reliability is between the client's target and my reliability commitment? @@ -755,7 +755,7 @@ Settlement uses a **blended** reliability measure (recent plus longer-term uptim Example: you publish **reliability commitment 99%**, the client chose **target 95%**, and the **blended** measure is **~97%**. - **Credits** are evaluated against the client's **target** (95%), not your reliability commitment. -- Because that blended 97% is above 95%, you **owe no SLA credit** for that day. Raw uptime alone does not decide this: a day with 97% raw uptime can still carry a partial credit if the blended measure falls below the target. +- A blended 97% is above a 95% target, but that is not a zero-credit day. The credit can still be larger than the SLA fee. Raw uptime alone does not decide the result. - **SLA fees** are priced from your **reliability commitment**, confidence, and the client's target — a higher reliability commitment relative to the target generally means lower client charges. The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what drives service-credit eligibility. @@ -763,17 +763,17 @@ The **reliability commitment** is your belief and pricing knob. The client's **r ### If the client's target is missed -A single bad day can wipe out weeks or months of SLA fees. In the example below, a day about 1–2 points below the client's target (~93–94% blended, not a day that exactly meets the target) costs about 44 days of collected SLA fees, and a full outage day costs about 88 days. These figures are illustrative. They do not come from the same pricing curve as the backtester sample. Use **Set Pricing → SLA** or the backtester for your machine's actual fee. Lower renter targets carry lower fees for a similar credit, so the ratio can be higher than this example. Review the economics below and run the [backtester](/host/sla-backtester) before enabling SLA. +A single bad day can wipe out weeks or months of SLA fees. In this example, a day that lands on the renter's target costs about half of that day's covered compute (on the order of the −$42 row), not one day's SLA fee. A day a point or two below costs more than that. A full outage day is on the order of a full day of compute (the −$84 row). These figures are illustrative. Use **Set Pricing → SLA** or the backtester for your machine. Review the economics below before enabling SLA. -These scenarios show settlement when the blended measure falls **below** a 95% client target. They are illustrations, not typical strong days: +These scenarios are illustrations for a 95% client target, not a quote: | Measured reliability (simplified) | You net (per day) | | --- | --- | -| Blended measure ~93–94% (illustrative shortfall) | −$42 (credit you owe) | +| About the target | −$42 (about half of that day's covered compute) | | Well below target (~90% or less) | −$84 (large credit owed) | -To put the asymmetry in perspective: at about $0.97/day in SLA fees, it takes roughly 44 strong days to accumulate the $42 you could lose on a single day about 1–2 points below the target. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use a 99% commitment, Medium confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. +To put the asymmetry in perspective: at about $0.97/day in SLA fees, it takes roughly 44 strong days to accumulate the $42 you could lose on a single day that lands on the renter's target. A day a point or two below costs more than that. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use a 99% commitment, Medium confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. Your SLA loss on a normal settlement day is tied to that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). Vast does not publish whether the closing settlement on a contract's last day can exceed that. Use the backtester's largest simulated day as a planning figure, not a cap. @@ -885,7 +885,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep c. **Run the self-test** (`vastai self-test machine MACHINE_ID`; see [Self-test](/host/upgrade-docker-and-packages#self-test)). - **If the last line is `Test completed successfully.`**, go to step d. - - **If it refuses to start** (`currently_rented`, `zero_active_offers`, or offer reliability at or below 0.90), stay listed without SLA. `currently_rented` stays until that rental ends. A **Save** that just extended it can push the end date out by days or weeks, and a machine listed without SLA can be rented again before you test. Do not pass `--ignore-requirements`. That flag skips these checks. If you need SLA on before the test can run, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID. + - **If it refuses to start** (`currently_rented`, `zero_active_offers`, or offer reliability at or below 0.90), stay listed without SLA. `currently_rented` stays until that rental ends. A **Save** that just extended it can push the end date out by days or weeks, and a machine listed without SLA can be rented again before you test. Do not pass `--ignore-requirements`. It does not get past `currently_rented`, `zero_active_offers`, or `offline_or_not_listed`. It only skips later requirement checks, such as the reliability threshold. If you need SLA on before the test can run, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID. - **If it runs and fails a check**, unlist, fix the machine using [How to self-test](/host/how-to-self-test), and repeat from step a. d. **Re-enable SLA.** Re-enter the SLA terms and click **Save**. This second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. Check the date in step a before you click it. @@ -995,9 +995,12 @@ This endpoint is rate-limited. Poll `GET /api/v0/users/me/machine-earnings/` at ```bash day=$(( $(date -u +%s) / 86400 - 1 )) curl -s -H "Authorization: Bearer $VAST_API_KEY" \ - "https://console.vast.ai/api/v0/users/me/machine-earnings/?sday=$day&eday=$day" + "https://console.vast.ai/api/v0/users/me/machine-earnings/?sday=$day&eday=$day" \ + | jq '{summary, per_machine: [.per_machine[]? | {machine_id, sla_earn}]}' ``` +The full response also includes billing identity (name, email, address, tax info) and the account balance. In a cron job, keep only `per_machine`, `per_day`, and `summary`. + **Automation pattern:** There is no host webhook for SLA settlement. One fleet call with `sday` and `eday` set to the same day index returns that UTC day for every machine in `per_machine[]`. Use `machid` only for a spot check. Do not use `per_day[].sla_earn` for a single machine. `last_days=1` is coarse: it covers yesterday and the current UTC day so far, not one settled day. diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index b590c366..a5625577 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -564,7 +564,7 @@ Test completed successfully. The last line must be `Test completed successfully.` -- **If it refuses to start** (offer reliability at or below 0.90, `currently_rented`, or `zero_active_offers`): stay listed without SLA. `currently_rented` clears when that rental ends, which can be a long time if the contract was just extended. Do not pass `--ignore-requirements` to turn SLA back on. +- **If it refuses to start** (offer reliability at or below 0.90, `currently_rented`, or `zero_active_offers`): stay listed without SLA. `currently_rented` clears when that rental ends, which can be a long time if the contract was just extended. Do not pass `--ignore-requirements` to turn SLA back on. It does not clear `currently_rented` or `zero_active_offers`. It only skips later requirement checks, such as the reliability threshold. - **It runs and fails a check:** the output names the check. See [How to self-test](/host/how-to-self-test). If you already relisted an SLA machine, unlist it. diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 28dead7a..47ca13a2 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -17,7 +17,7 @@ On an existing listing, omitted GPU price, bandwidth prices, reserved discount, **Other cautions:** - **Passing `-e` or `-l` can extend active rentals,** including SLA contracts. Normal CLI output does not print that. Pass `--raw` and read `.results[0].upd_contracts`. -- **After an unlist, the relist is a new ask.** Omitted `-u`/`-d` publish $0 bandwidth, omitted `-r` becomes `0.4`, and omitted `-m` becomes 1. Pass all of them. +- **After an unlist, the relist is a new ask.** Omitted `-u`/`-d` publish $0 bandwidth, omitted `-r` becomes `0.4`, and omitted `-m` becomes 1. Pass all of them, including `-g` for the GPU price. A new ask without a GPU price returns HTTP 400. - **`-m` defaults to 1.** The CLI always sends `min_chunk`, using 1 when you omit `-m`. On an existing listing the server does not use that value to resplit the machine. On a first listing, or a relist after unlist, 1 splits the machine into single-GPU offers, and each one can be its own SLA contract. Always pass `-m` with the min GPU count you intend. - **`vastai list machines` (plural)** applies the same resets and extensions to every ID. Do not use it on SLA or hidden listings. To change price or SLA terms on several machines, update each one with the [read → merge → PUT flow](/host/sla-offers#update-sla-on-an-existing-ask-partial-body) or use **Set Pricing**. The [fleet SLA re-list loop](/host/sla-offers#fleet-sla-re-list-machines-that-already-have-an-sla) only restores listed SLA offers that are missing from search, on machines with no rentals. It does not change prices. A hidden listing is also missing from search, so set `HIDDEN_IDS` or the live run makes it public. From 74413cbf33a99dea816ca6c104abd2d3440b3068 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 08:34:38 -0700 Subject: [PATCH 243/250] docs(sla): address doc-review consensus (cycle 187) Every page now uses the same settlement rule: a day on the target still pays about half of that day's covered compute. Co-authored-by: Cursor --- api-reference/permissions.mdx | 1 + guides/instances/choosing/sla-coverage.mdx | 18 +++++++++--------- host/sla-offers.mdx | 18 +++++++++--------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index 2720f7f4..b7100521 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -173,6 +173,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | SLA backtester | `machine_read` | Console SLA preview | | Schedule / cancel maintenance | `machine_write` | [Set a maintenance window](/host/set-maintenance-window) (Host → Machines → Settings → Machine Maintenances), or CLI/REST. SLA service-credit rules: [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). | | Confirm windows (`vastai show maints`) | `instance_read` | **Machine Maintenances** or **Scheduled Maintenances**. | +| Run `vastai self-test machine` | `machine_read`, `instance_read`, `instance_write`, and `misc` (offer search), on one key | The command rents and then destroys a test instance. | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings (console billing needs no API key; API earnings need `billing_read`). Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | | Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10` (`verified=any` is often required when checking your own machine). | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 1bf23186..009be93e 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability commitment on an **on-demand** rental. You set a **Reliability target** before you rent and pay an hourly **SLA fee**. If measured reliability falls below your target, you receive a **service credit**. Searching or filtering by reliability does not turn an SLA on. Set a **Reliability target** and confirm an **SLA Fee** line before you click **RENT**. See [Settlement timing](#settlement-timing) for how fees and credits show up on Charges. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability commitment on an **on-demand** rental. You set a **Reliability target** before you rent and pay an hourly **SLA fee**. Settlement is a smooth curve: the credit is small when uptime is well above your target, about half of that day's covered compute when the day lands on your target, and close to a full day of covered compute when uptime is far below it. Searching or filtering by reliability does not turn an SLA on. Set a **Reliability target** and confirm an **SLA Fee** line before you click **RENT**. See [Settlement timing](#settlement-timing) for how fees and credits show up on Charges. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -16,13 +16,13 @@ An SLA is an optional reliability promise on an **on-demand** GPU rental. You do 2. **You** choose a **reliability target**: how much uptime you want. A higher target costs more. 3. You pay an **SLA fee** (a service level fee) on top of the GPU price. 4. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. -5. If that blended measure met your reliability target, no credit is owed. If it fell short, you receive a **service credit**. Because longer-term uptime is included, a single bad day after a stretch of good uptime can produce a smaller credit than that day's raw uptime suggests. The reverse is also true: raw uptime at or slightly above your target can still produce a partial credit when the blended measure is below it. +5. The credit depends on how far that blended measure sits relative to your target. It is small when reliability is well above your target, about half of that day's covered compute at your target, and close to a full day's covered compute far below it. Settlement is a smooth curve, not pass/fail. Because longer-term uptime is included, one bad day after good days usually pays less than that day's raw uptime suggests. 6. That credit can be larger than the SLA fee you paid that day. A few things people mix up: - The **reliability score** on an offer card is a separate marketplace signal. It is not your SLA. -- The GPU bill does **not** stop during an outage. A credit is paid only when the blended measure falls below your target, usually after the next UTC midnight. A short outage that stays above the target is billed in full with no credit. +- The GPU bill does **not** stop during an outage. The day's credit grows the further the blended measure falls, and a day near your target still pays a credit. Settlement is usually after the next UTC midnight. - Filtering for SLA offers does not turn on an SLA. Set **Reliability target** in the Search filters before you click **RENT**. - SLA is only for **on-demand** rentals, not interruptible (spot) or reserved rentals. - If the Search offer has **no SLA Fee** line, renting it gives you no SLA. On an instance, that line appears only while the instance is **running**. For how SLA amounts appear in **Charges**, see [Settlement timing](#settlement-timing). @@ -358,7 +358,7 @@ When you rent an SLA-backed offer **with a target set**: 1. **Contract terms lock in** — your reliability target, the host's reliability commitment, and the rental end date are fixed for that rental. The host's pricing margin is also fixed, and it is not shown to you. When comparing offers, use the SLA fee line or `dph_total`. An SLA does not extend **Max Duration**. Reaching that end date is not an outage, so no credit is owed for the expiry itself. At the end date the instance stops and cannot be restarted. It may be deleted 48 hours later. Copy your data off before then. See [Contract Expiration](/guides/instances/manage-instances#contract-expiration). The host may extend the rental on the same terms. 2. **Charges and settlement** — compute, storage, and the SLA fee accrue while the rental contract is active, **including while the machine is offline**. That is different from a non-SLA rental. The net SLA row (SLA fee minus any service credit) settles once per UTC day. See [Settlement timing](#settlement-timing) and [What you pay during an outage](#what-you-pay-during-an-outage). 3. **Daily settlement** — Vast measures reliability across multiple timescales and calculates any SLA credit. -4. **Credits appear in billing** — service credits improve your balance; strong days mean you paid the SLA fee with no credit. +4. **Credits appear in billing** — each UTC day nets the SLA fee against that day's credit. On strong days the credit is small. On days near or below your target it is larger. ### What you pay during an outage @@ -370,7 +370,7 @@ Billing continues during downtime. You are still charged for **compute, storage, During an outage the Instances price popover may say "Machine is offline. You're not being charged." That message does not apply to SLA rentals: compute, storage, and the SLA fee continue while the contract is active. The **SLA Fee** line is hidden, and `slaPremiumPerHour` reads `0`, while an instance is stopped, loading, or offline. Neither means the charges have stopped. -**This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit is paid only when the blended measure falls below your target. +**This is different from non-SLA rentals.** Normally you are not charged while a machine is offline (see [Billing](/guides/reference/billing)). On an SLA contract you are billed for GPU compute, storage, and the SLA fee, and a service credit can still be paid on a day that meets your target. **Stop vs destroy.** @@ -399,11 +399,11 @@ Using the H100 example ($84/day compute, ~$0.97/day SLA fee, target 95%, host re | Scenario | Approx. SLA fee | Approx. service credit | Credit minus SLA fee | | --- | --- | --- | --- | -| Well above the target | ~$0.97/day | Small | You can still pay more than the SLA fee | -| About the target | ~$0.97/day | About half of that day's covered compute | On the order of **+$41** in this example | -| Short outage (about 1 hour) | ~$0.97/day | Not zero if the day is near the target | Plus about $3.50 of GPU billed for that hour | +| About the target | ~$0.97/day | ~$42 | **+$41** | | Severe shortfall (~90% or less) | ~$0.97/day | ~$84 | **+$83** | +Well above the target, the credit is small and can still exceed the day's SLA fee. In a short outage of about an hour, GPU for that hour (about $3.50 in this example) is still billed. It is not part of the credit. + These rows assume the shortfall lasts long enough that the blended measure is that low. A single bad day after several good days usually pays less than the row, because the good days are still in the blend. **How to read “Credit minus SLA fee”:** this column is only the service credit minus the SLA fee. It is not your net versus a non-SLA rental. On an SLA rental, offline time is still billed as GPU compute, storage, and the SLA fee. On a non-SLA rental it is not, so add that billed downtime when you compare the two. Credits grow with the size of the shortfall. Settlement is a smooth curve, not pass/fail. A day at your target still pays a credit of about half of that day's covered compute. A day a point or two below pays more. Figures are illustrative. Raw daily uptime and the blended measure are not the same number. @@ -422,7 +422,7 @@ Production settlement uses the multi-window reliability blend described above, n ## If your instance goes down -1. Turn on **Instance offline** and **Instance back online** ([Notifications](/guides/reference/notifications)) so you can decide quickly whether to wait or **Destroy**. If you can still reach the instance, save work. If the machine is offline, you may not be able to copy data off it. You can wait (compute, storage, and the SLA fee keep billing; a credit applies only if that day's blended measure falls below your target) or **Destroy** (charges stop and the disk is deleted). Check **Instances** for host or maintenance status. +1. Turn on **Instance offline** and **Instance back online** ([Notifications](/guides/reference/notifications)) so you can decide quickly whether to wait or **Destroy**. If you can still reach the instance, save work. If the machine is offline, you may not be able to copy data off it. You can wait (compute, storage, and the SLA fee keep billing; a credit can still apply on a day that meets your target) or **Destroy** (charges stop and the disk is deleted). Check **Instances** for host or maintenance status. 2. Remember: compute, storage, and SLA fees continue until you destroy the instance. Credits are calculated at the next UTC settlement and apply to the **previous UTC day**, not the current hour. 3. **Console:** Open **Instances**, select the instance, then **Destroy** to end charges on an unavailable SLA instance. See [Stop vs destroy](#what-you-pay-during-an-outage). Destroy deletes the disk, so copy off anything you need first. 4. After the UTC day settles, check **Account → Billing → Charges** or `GET /api/v0/charges/` for the net SLA row. Invoices do not show SLA credits. diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 946b654b..86f269d2 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -4,7 +4,7 @@ description: "Offer an SLA on your machines: set a reliability commitment and co "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability commitment, paid as daily service credits, not as guaranteed uptime: clients who choose an SLA pay a small hourly **SLA fee** included in **`dph_total`** (dollars per hour total in search — GPU + storage + SLA fee), and if measured reliability falls short of their chosen target, they receive a service credit funded from your earnings. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability commitment, paid as daily service credits, not as guaranteed uptime: clients who choose an SLA pay a small hourly **SLA fee** included in **`dph_total`** (dollars per hour total in search — GPU + storage + SLA fee), The renter pays that fee. You may owe them a service credit from your earnings. The credit is small when uptime is well above their target, and about half of that day's covered compute when the day lands on the target. The **SLA fee** is that hourly amount. It appears as the **SLA Fee** line in the console. API field names call the same amount a premium (for example `slaPremiumPerHour`). @@ -13,7 +13,7 @@ The **SLA fee** is that hourly amount. It appears as the **SLA Fee** line in the This page explains how SLA offers work from the host side — what you set, how clients choose an SLA, and what happens when uptime is good or bad. -SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; on bad days, service credits can exceed the fees you collected. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**, also needs rental history; a new machine shows "No historical data available for this machine yet"). +SLA settlement is **asymmetric by design**: on strong days the credit is small and can still exceed that day's SLA fee; on days near or below the target, the credit is much larger. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**, also needs rental history; a new machine shows "No historical data available for this machine yet"). @@ -25,7 +25,7 @@ SLA settlement is **asymmetric by design**: on strong days you keep the SLA fee; Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. -You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. Outage recovery, including when to turn SLA back on, is in [Severe outage](#severe-outage). A full-access key covers this page. A scoped key needs `billing_read`, `machine_read`, `machine_write`, `instance_read`, and `misc` for the offer search the self-test runs. See the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). +You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. Outage recovery, including when to turn SLA back on, is in [Severe outage](#severe-outage). A full-access key covers this page. For a scoped key, see the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). The self-test rents and destroys a test instance, so that key also needs `instance_write`. | Goal | Start here | @@ -132,7 +132,7 @@ When a client rents an on-demand instance on your SLA-listed offer with a chosen - While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA fee** — including during downtime. Settlement credits for missed targets are calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA fee at the quoted allocation — **not** bandwidth. - Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. -- **Strong reliability relative to the client's target** → you keep the SLA fee for that day. +- **Strong reliability relative to the client's target** → a small credit, which can still exceed that day's SLA fee. - **Shortfalls** → credits flow to the client from your earnings. On a normal day, the credit can be as large as that day's rental charges for the contract. See [SLA and GPU slicing](#sla-and-gpu-slicing) for the last-day caveat. Over many strong days, SLA fees can offset occasional credits, but a single bad day can exceed months of collected SLA fees — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. @@ -310,7 +310,7 @@ SLA listing via CLI/SDK is not available yet — use the REST API below (or cons #### Update SLA on an existing ask (partial body) -**Not a first listing.** Use this SLA-only body when the machine already has base pricing. For a **first publish**, or a relist after unlist, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include `price_gpu`, `min_chunk`, disk and bandwidth prices, and `end_date`). A new ask without `price_gpu` returns HTTP 400. or **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). +**Not a first listing.** Use this SLA-only body when the machine already has base pricing. For a **first publish**, or a relist after unlist, use a full `create_asks` body from [List Machine](/api-reference/machines/list-machine) (include `price_gpu`, `min_chunk`, disk and bandwidth prices, and `end_date`). A new ask without `price_gpu` returns HTTP 400. You can also set the same fields in **Set Pricing → SLA** in the console. See [Hosting overview](/host/hosting-overview#offers-and-rental-contracts). Some omitted fields reset to defaults (for example `price_disk`, `hidden_listing`, and `duration`). Read the warning under [Full listing update](#full-listing-update-existing-ask) before you copy a body. `"vol_size": 0` keeps a new volume offer from being created. It does not delete a volume offer you already have. @@ -742,9 +742,9 @@ In the **You net** column, values follow host earnings sign conventions: positiv | Blended reliability vs the client's target | You net (per day) | | --- | --- | -| Well above the target (for example blended ~99% vs a 95% target) | A small credit, which can still exceed that day's SLA fee | +| About the target (95% blended vs a 95% target) | −$42 | -These rows are not raw uptime. Meeting the target does not mean the credit is zero. +This row is not raw uptime. Well above the target, the credit is smaller, and it can still exceed that day's SLA fee. Meeting the target does not mean the credit is zero. Settlement uses a **blended** reliability measure (recent plus longer-term uptime), not the day's raw uptime alone. Raw uptime and the blended measure are not the same number. A day at the target still settles with a credit of about half of that day's covered compute. @@ -773,7 +773,7 @@ These scenarios are illustrations for a 95% client target, not a quote: | About the target | −$42 (about half of that day's covered compute) | | Well below target (~90% or less) | −$84 (large credit owed) | -To put the asymmetry in perspective: at about $0.97/day in SLA fees, it takes roughly 44 strong days to accumulate the $42 you could lose on a single day that lands on the renter's target. A day a point or two below costs more than that. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use a 99% commitment, Medium confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. +To put the asymmetry in perspective: at about $0.97/day in SLA fees, a day that lands on the renter's target costs about $42, which is roughly 44 days of SLA fees. Strong days are not pure fee income: the credit on those days is small and can still exceed the fee. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use a 99% commitment, Medium confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. Your SLA loss on a normal settlement day is tied to that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). Vast does not publish whether the closing settlement on a contract's last day can exceed that. Use the backtester's largest simulated day as a planning figure, not a cap. @@ -781,7 +781,7 @@ Your SLA loss on a normal settlement day is tied to that day's covered compute * ### Reliability commitment 99%, delivered 99.5% -You outperform your reliability commitment. Clients who chose targets at or below 99% pay small SLA fees; credits are rare. You net positive on SLA over time. +You outperform your reliability commitment. Clients who chose targets at or below 99% pay small SLA fees. Credits on those days are small. Whether you net positive depends on how far delivered reliability sits above the break-even level in the backtester. ### Reliability commitment 99% with an offline day From 9008e716871952f408a24a930342b3cb03549f2e Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 08:44:52 -0700 Subject: [PATCH 244/250] docs(sla): address doc-review consensus (cycle 188) A day well above the target keeps most of the SLA fee, and the self-test key must include offer search. Co-authored-by: Cursor --- api-reference/openapi.yaml | 2 +- api-reference/openapi/yaml/sla_backtest.yaml | 2 +- api-reference/permissions.mdx | 13 +++++++++ guides/instances/choosing/find-and-rent.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 6 ++-- host/sla-backtester.mdx | 4 +-- host/sla-offers.mdx | 29 ++++++++++---------- 7 files changed, 36 insertions(+), 22 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 83650417..045543eb 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9645,7 +9645,7 @@ paths: start_day: 20567 end_day: 20657 r_eff: 0.9987 - r_be: 0.9712 + r_be: 0.996 days: - day: 20567 client_compute_to_escrow: 78.12 diff --git a/api-reference/openapi/yaml/sla_backtest.yaml b/api-reference/openapi/yaml/sla_backtest.yaml index c4f4ce7b..83378ffb 100644 --- a/api-reference/openapi/yaml/sla_backtest.yaml +++ b/api-reference/openapi/yaml/sla_backtest.yaml @@ -168,7 +168,7 @@ paths: start_day: 20567 end_day: 20657 r_eff: 0.9987 - r_be: 0.9712 + r_be: 0.9960 days: - day: 20567 client_compute_to_escrow: 78.12 diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index b7100521..a61f9718 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -157,6 +157,19 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do } ``` +**Self-test** (`vastai self-test machine`) searches offers, then rents and destroys a test instance. That requires one key, not the listing key above: + +```json +{ + "api": { + "machine_read": {}, + "instance_read": {}, + "instance_write": {}, + "misc": {} + } +} +``` + **Verify offers in search** — add `misc` on a **separate**, narrowly scoped key (`misc` also covers serverless and other routes—not search only): ```json diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index 05f40430..d742ceb7 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -19,7 +19,7 @@ You will find various search options on the top and left control bars that allow ## Offer card -The offer card shows the details of a machine available for rent, including specs, pricing, and the maximum rental duration. When you rent an instance, a rental contract is created between you and the host based on the offer's current terms. Once you rent, those GPUs are yours for the length of the contract. The host's listing may keep offering the machine's remaining GPUs to other renters until its end date or until the host unlists it. +The offer card shows the details of a machine available for rent, including specs, pricing, and the maximum rental duration. When you rent an instance, a rental contract is created between you and the host based on the offer's current terms. For an on-demand rental, the GPUs stay reserved while the instance is running. If you stop it, those GPUs may be rented to someone else, and resuming can fail until they free up. Interruptible rentals can be outbid at any time. The host's listing may keep offering the machine's remaining GPUs to other renters until its end date or until the host unlists it. Most of the items on the offer card can be filtered using the search filters. Some of the important parts are the price and the maximum rental duration. Hovering over the price shows the different prices for GPU rental, storage, and bandwidth. diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 009be93e..43b25200 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability commitment on an **on-demand** rental. You set a **Reliability target** before you rent and pay an hourly **SLA fee**. Settlement is a smooth curve: the credit is small when uptime is well above your target, about half of that day's covered compute when the day lands on your target, and close to a full day of covered compute when uptime is far below it. Searching or filtering by reliability does not turn an SLA on. Set a **Reliability target** and confirm an **SLA Fee** line before you click **RENT**. See [Settlement timing](#settlement-timing) for how fees and credits show up on Charges. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability commitment on an **on-demand** rental. You set a **Reliability target** before you rent and pay an hourly **SLA fee**. Settlement is a smooth curve, not pass/fail. Covered compute is that day's GPU, storage, and bandwidth charges for the rental. The credit is usually smaller than the SLA fee when uptime is well above your target, about half of that day's covered compute when the day lands on your target, and close to a full day of covered compute when uptime is far below it. Searching or filtering by reliability does not turn an SLA on. Set a **Reliability target** and confirm an **SLA Fee** line before you click **RENT**. See [Settlement timing](#settlement-timing) for how fees and credits show up on Charges. This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -16,7 +16,7 @@ An SLA is an optional reliability promise on an **on-demand** GPU rental. You do 2. **You** choose a **reliability target**: how much uptime you want. A higher target costs more. 3. You pay an **SLA fee** (a service level fee) on top of the GPU price. 4. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. -5. The credit depends on how far that blended measure sits relative to your target. It is small when reliability is well above your target, about half of that day's covered compute at your target, and close to a full day's covered compute far below it. Settlement is a smooth curve, not pass/fail. Because longer-term uptime is included, one bad day after good days usually pays less than that day's raw uptime suggests. +5. The credit depends on how far that blended measure sits relative to your target. Well above your target it is usually smaller than that day's SLA fee. At your target it is about half of that day's covered compute (GPU, storage, and bandwidth). Far below your target it is close to a full day of covered compute. Settlement is a smooth curve, not pass/fail. Because longer-term uptime is included, one bad day after good days usually pays less than that day's raw uptime suggests. 6. That credit can be larger than the SLA fee you paid that day. A few things people mix up: @@ -402,7 +402,7 @@ Using the H100 example ($84/day compute, ~$0.97/day SLA fee, target 95%, host re | About the target | ~$0.97/day | ~$42 | **+$41** | | Severe shortfall (~90% or less) | ~$0.97/day | ~$84 | **+$83** | -Well above the target, the credit is small and can still exceed the day's SLA fee. In a short outage of about an hour, GPU for that hour (about $3.50 in this example) is still billed. It is not part of the credit. +Well above the target, the credit is usually smaller than that day's SLA fee (about $0.03 in this example, against a ~$0.97 fee). Near or below the target, the credit grows quickly. In a short outage of about an hour, GPU for that hour (about $3.50 in this example) is still billed. It is not part of the credit. These rows assume the shortfall lasts long enough that the blended measure is that low. A single bad day after several good days usually pays less than the row, because the good days are still in the blend. diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index c2aa3974..57800a56 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -156,7 +156,7 @@ A successful response looks like this (one `days` row shown). These numbers are "start_day": 20567, "end_day": 20657, "r_eff": 0.9987, - "r_be": 0.9712, + "r_be": 0.9960, "days": [ { "day": 20567, @@ -183,7 +183,7 @@ A successful response looks like this (one `days` row shown). These numbers are | `has_data` | `true` if the range had at least one day of rental activity to replay. `false` means no usable history in the window. Move the window toward the present, or wait for more rental history. Older windows may have no recorded SLA history. When `false`, every `days` row is zero with `reliability: null`, and `r_eff` is `null`. | | `start_day`, `end_day` | UTC day indices, `day = floor(epoch_seconds / 86400)`. `day × 86400` is exactly 00:00 UTC on that date. Convert with `date -u -d "@$((day * 86400))" +%F` (Linux) or `date -u -r $((day * 86400)) +%F` (macOS). Show Earnings `sday` / `eday` use the same day index. | | `r_eff` | **Effective reliability**: the constant reliability that would have produced the service credits paid in this window. `null` when nothing was paid into escrow in the window (all `client_*_to_escrow` values are zero, as with `has_data: false`). | -| `r_be` | **Break-even reliability**: the reliability at which SLA fees and service credits cancel out. Always present. | +| `r_be` | **Break-even reliability**: the reliability at which SLA fees and service credits cancel out. Always present. In this example it sits above `r_target`. At the target itself, the credit is about half of that day's covered compute, far more than the SLA fee. Headroom is the gap between `r_eff` and `r_be`, not the gap between `r_eff` and `r_target`. | | `days` | One row per UTC day from `start_day` to `end_day` (see below). | | `params` | The SLA terms the replay actually used: `r_claim`, `r_target` (after defaulting), `p`, and the automatically derived `beta`. | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 86f269d2..81421095 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -4,7 +4,7 @@ description: "Offer an SLA on your machines: set a reliability commitment and co "canonical": "/host/sla-offers" --- -Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability commitment, paid as daily service credits, not as guaranteed uptime: clients who choose an SLA pay a small hourly **SLA fee** included in **`dph_total`** (dollars per hour total in search — GPU + storage + SLA fee), The renter pays that fee. You may owe them a service credit from your earnings. The credit is small when uptime is well above their target, and about half of that day's covered compute when the day lands on the target. +Vast.ai lets hosts attach a **Service Level Agreement (SLA)** to a machine listing. An SLA is a reliability commitment, not guaranteed uptime. The renter pays a small hourly **SLA fee** included in **`dph_total`** (dollars per hour total in search: GPU + storage + SLA fee). You may owe that renter a service credit from your earnings. The credit is small when uptime is well above their target, and about half of that day's covered compute when the day lands on the target. The **SLA fee** is that hourly amount. It appears as the **SLA Fee** line in the console. API field names call the same amount a premium (for example `slaPremiumPerHour`). @@ -13,7 +13,7 @@ The **SLA fee** is that hourly amount. It appears as the **SLA Fee** line in the This page explains how SLA offers work from the host side — what you set, how clients choose an SLA, and what happens when uptime is good or bad. -SLA settlement is **asymmetric by design**: on strong days the credit is small and can still exceed that day's SLA fee; on days near or below the target, the credit is much larger. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**, also needs rental history; a new machine shows "No historical data available for this machine yet"). +SLA settlement is **asymmetric by design**: well above the client's target the day's credit is smaller than the SLA fee, and you keep the difference. Between the client's target and break-even (`r_be`), and at the target itself, the credit can exceed the fee. On a day at the target it is about half of that day's covered compute. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**, also needs rental history; a new machine shows "No historical data available for this machine yet"). @@ -25,7 +25,7 @@ SLA settlement is **asymmetric by design**: on strong days the credit is small a Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. -You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. Outage recovery, including when to turn SLA back on, is in [Severe outage](#severe-outage). A full-access key covers this page. For a scoped key, see the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). The self-test rents and destroys a test instance, so that key also needs `instance_write`. +You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. Outage recovery, including when to turn SLA back on, is in [Severe outage](#severe-outage). A full-access key covers this page. `vastai self-test machine` searches offers, then rents and destroys a test instance. If you use a scoped key for it, that one key needs `machine_read`, `instance_read`, `instance_write`, and `misc`. The listing key in the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe) cannot run the self-test. | Goal | Start here | @@ -42,12 +42,12 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. You need it for per-machine SLA earnings and, if you later unlist during an outage, for `vastai self-test machine`. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. Outage recovery is in [Severe outage](#severe-outage), not in this checklist. +3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. You need it for per-machine SLA earnings and, if you later unlist during an outage, for `vastai self-test machine`. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The self-test needs its own scoped key: `machine_read`, `instance_read`, `instance_write`, and `misc` on that one key. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. Outage recovery is in [Severe outage](#severe-outage), not in this checklist. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. - **All hosts:** After you enable SLA, GPU earnings in **Host → Billing** can drop. That compute is paid out later as SLA earnings, and much of it can stay held until the contract ends. A lower total is not by itself a credit. - - **API users:** Read the held amount as `sla_earn`. See [Monitoring SLA after listing](#monitoring-sla-after-listing). + - **API users:** Read daily SLA releases as `per_machine[].sla_earn`. This is money released to you that day, not the amount still held. See [Monitoring SLA after listing](#monitoring-sla-after-listing). 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Account Settings → Notification Settings** (Host group) for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. **Enable SLA.** - **Do this:** In **Set Pricing → SLA**, enter **Reliability Commitment** as a percent (the field ends with `%`; type `99` for 99%). Set **Confidence**. Start at **Low** unless you have rental history. Then click **Save**. @@ -99,7 +99,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. Settlement is a smooth curve around the renter's target, not a pass/fail line. Well above the target, the credit is small but can still exceed that day's SLA fee. At the target, the credit is about half of that day's covered compute. Further below, it approaches a full day of covered compute. The renter's **service credit** comes from your earnings. Vast holds SLA rental pay and releases it over time, so a low earnings day is not by itself a credit. Details are in [Billing vs settlement](#billing-vs-settlement-important). +6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. Settlement is a smooth curve around the renter's target, not a pass/fail line. Well above the target (above break-even, `r_be`), the day's credit is smaller than the SLA fee. Between the target and `r_be`, the credit can exceed the fee. At the target, the credit is about half of that day's covered compute. Further below, it approaches a full day of covered compute. The renter's **service credit** comes from your earnings. Vast holds SLA rental pay and releases it over time, so a low earnings day is not by itself a credit. Details are in [Billing vs settlement](#billing-vs-settlement-important). 7. One bad day can cost more than many days of fees. What this is not: @@ -132,7 +132,7 @@ When a client rents an on-demand instance on your SLA-listed offer with a chosen - While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA fee** — including during downtime. Settlement credits for missed targets are calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA fee at the quoted allocation — **not** bandwidth. - Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. -- **Strong reliability relative to the client's target** → a small credit, which can still exceed that day's SLA fee. +- **Well above the client's target** (above break-even) → the day's credit is smaller than the SLA fee, and you keep the difference. - **Shortfalls** → credits flow to the client from your earnings. On a normal day, the credit can be as large as that day's rental charges for the contract. See [SLA and GPU slicing](#sla-and-gpu-slicing) for the last-day caveat. Over many strong days, SLA fees can offset occasional credits, but a single bad day can exceed months of collected SLA fees — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. @@ -736,15 +736,16 @@ vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 - | jq '[.[] | select(.is_bid == false) | {id, num_gpus, dph_total, expected_reliability, reliability}]' ``` -### If reliability is strong relative to the client's target +### If blended reliability lands on or above the client's target -In the **You net** column, values follow host earnings sign conventions: positive means SLA fee you kept; negative means credit you owed the client. +Net per day is the SLA fee you keep minus the credit you owe. Positive means you kept fee. Negative means you owed a credit. Figures are the H100 example: $84/day compute, ~$0.97/day SLA fee, client target 95%. These rows are not raw uptime. -| Blended reliability vs the client's target | You net (per day) | -| --- | --- | -| About the target (95% blended vs a 95% target) | −$42 | +| Blended reliability | Credit owed | Net for you | +| --- | --- | --- | +| Well above the target (~99%) | ~$0.03 | about +$0.94 | +| About the target (~95%) | ~$42 | about −$42 | -This row is not raw uptime. Well above the target, the credit is smaller, and it can still exceed that day's SLA fee. Meeting the target does not mean the credit is zero. +Above break-even (about 97.2% in this example) you keep most of the fee. At the target the credit is about half of that day's covered compute. Meeting the target does not mean the credit is zero. Settlement uses a **blended** reliability measure (recent plus longer-term uptime), not the day's raw uptime alone. Raw uptime and the blended measure are not the same number. A day at the target still settles with a credit of about half of that day's covered compute. @@ -773,7 +774,7 @@ These scenarios are illustrations for a 95% client target, not a quote: | About the target | −$42 (about half of that day's covered compute) | | Well below target (~90% or less) | −$84 (large credit owed) | -To put the asymmetry in perspective: at about $0.97/day in SLA fees, a day that lands on the renter's target costs about $42, which is roughly 44 days of SLA fees. Strong days are not pure fee income: the credit on those days is small and can still exceed the fee. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use a 99% commitment, Medium confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. +To put the asymmetry in perspective: at about $0.97/day in SLA fees, a day that lands on the renter's target costs about $42, which is roughly 44 days of SLA fees. On days well above the target the credit is about $0.03, so you keep most of the ~$0.97 fee. A day between the target and break-even (about 97.2% here) can still cost more than that day's fee. A full outage day, about $84 of compute plus the ~$0.97 fee, is roughly 88 days of fees. The SLA fee is still a small fraction of daily compute. These figures use a 99% commitment, Medium confidence, a 95% target, and $84/day of GPU compute. Use the console preview or the backtester for your own machine. Your SLA loss on a normal settlement day is tied to that day's covered compute **per SLA contract** (GPU, storage, and bandwidth). Vast does not publish whether the closing settlement on a contract's last day can exceed that. Use the backtester's largest simulated day as a planning figure, not a cap. From aa1df135ff17d99230373622d9a75651b54f1823 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 08:56:00 -0700 Subject: [PATCH 245/250] docs(sla): address doc-review consensus (cycle 189) The renter page leads with how to turn SLA on, and break-even is named before the economics. Co-authored-by: Cursor --- api-reference/openapi/yaml/show_earnings.yaml | 2 +- cli/reference/create-instance.mdx | 2 +- cli/reference/search-offers.mdx | 4 ++-- cli/reference/show-earnings.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-offers.mdx | 10 +++++----- snippets/host/cli/list-machine.mdx | 2 +- snippets/host/cli/self-test-machine.mdx | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/api-reference/openapi/yaml/show_earnings.yaml b/api-reference/openapi/yaml/show_earnings.yaml index 55b81fd7..fef2a817 100644 --- a/api-reference/openapi/yaml/show_earnings.yaml +++ b/api-reference/openapi/yaml/show_earnings.yaml @@ -177,5 +177,5 @@ x-cli-commands: per machine. endpoint: /api/v0/users/{user_id}/machine-earnings/ method: GET - example: vastai show earnings --start_date 2023-01-01 --end_date 2023-01-31 --machine_id + example: vastai show earnings --start_date 2023-01-01T00:00:00Z --end_date 2023-01-31T00:00:00Z --machine_id 123 diff --git a/cli/reference/create-instance.mdx b/cli/reference/create-instance.mdx index 62313461..ce2e8a74 100644 --- a/cli/reference/create-instance.mdx +++ b/cli/reference/create-instance.mdx @@ -178,7 +178,7 @@ The following options are available for all commands: | Option | Description | | --- | --- | | `--url URL` | Server REST API URL | -| `--retry N` | Retry limit | +| `--retry N` | Total attempts (default 3; use 1 for a single request; 0 sends nothing) | | `--raw` | Output machine-readable JSON | | `--explain` | Verbose explanation of API calls | | `--api-key KEY` | API key (defaults to `~/.config/vastai/vast_api_key`) | diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 171c22b2..36f92959 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -70,7 +70,7 @@ vastai search offers [--help] [--api-key API_KEY] [--raw] ## Description -Filter examples (including SLA quotes) are under [Examples](#examples). Query syntax for advanced filters is at the end of Examples. +Filter examples (including finding SLA offers) are under [Examples](#examples). Query syntax for advanced filters is at the end of Examples. ## Examples @@ -212,7 +212,7 @@ The following options are available for all commands: | Option | Description | | --- | --- | | `--url URL` | Server REST API URL | -| `--retry N` | Retry limit | +| `--retry N` | Total attempts (default 3; use 1 for a single request; 0 sends nothing) | | `--raw` | Output machine-readable JSON | | `--explain` | Verbose explanation of API calls | | `--api-key KEY` | API key (defaults to `~/.config/vastai/vast_api_key`) | diff --git a/cli/reference/show-earnings.mdx b/cli/reference/show-earnings.mdx index e71be72a..0d59c5be 100644 --- a/cli/reference/show-earnings.mdx +++ b/cli/reference/show-earnings.mdx @@ -57,7 +57,7 @@ The following options are available for all commands: | Option | Description | | --- | --- | | `--url URL` | Server REST API URL | -| `--retry N` | Retry limit | +| `--retry N` | Total attempts (default 3; use 1 for a single request; 0 sends nothing) | | `--raw` | Output machine-readable JSON | | `--explain` | Verbose explanation of API calls | | `--api-key KEY` | API key (defaults to `~/.config/vastai/vast_api_key`) | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 43b25200..0155ab44 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -4,7 +4,7 @@ description: "Rent GPU instances with an SLA. Learn how the SLA fee, reliability "canonical": "/guides/instances/choosing/sla-coverage" --- -Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability commitment on an **on-demand** rental. You set a **Reliability target** before you rent and pay an hourly **SLA fee**. Settlement is a smooth curve, not pass/fail. Covered compute is that day's GPU, storage, and bandwidth charges for the rental. The credit is usually smaller than the SLA fee when uptime is well above your target, about half of that day's covered compute when the day lands on your target, and close to a full day of covered compute when uptime is far below it. Searching or filtering by reliability does not turn an SLA on. Set a **Reliability target** and confirm an **SLA Fee** line before you click **RENT**. See [Settlement timing](#settlement-timing) for how fees and credits show up on Charges. +Some Vast.ai offers include a **Service Level Agreement (SLA)** — an optional reliability commitment on an **on-demand** rental. You pay an hourly **SLA fee** on top of the GPU price. It does not guarantee uptime. In the console, set **Reliability target** in Search filters and confirm an **SLA Fee** line before you click **RENT**. How the daily credit is sized is in [SLA in plain language](#sla-in-plain-language). This page explains SLA from the renter side: how to find SLA offers, how pricing works, and when you get credited. @@ -333,7 +333,7 @@ A timeout, a dropped connection, or HTTP 5xx means the rental may already exist. | SLA not available | HTTP 403 `sla_disabled` | SLA is not enabled. This is a single platform-wide switch, not an account or region setting. Do not retry in a loop. Rent without a reliability target, or contact support. | | Offer no longer exists | HTTP 400 `invalid_args` (`msg` may contain `error 404/3603`), HTTP 404 `no_such_ask` (`msg` may contain `error 404/3659` if the offer was taken mid-request), or HTTP 410 | Re-search and use a fresh offer ID. Do not retry the same ID. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | -| `price` (bid) sent together with `target_reliability` | HTTP 400 "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | +| `price` (bid) sent together with `target_reliability` | HTTP 400 `invalid_args`: "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | See [If the rent outcome is unknown](#if-the-rent-outcome-is-unknown). | | Too many requests | HTTP 429. Search returns JSON. `error` is `HTTPTooManyRequests` for a short limit, or `search_quota_exceeded` when the daily row quota is used up. Rent 429s are not that JSON shape (usually an HTML page). Both include `Retry-After`. | If `error` is `search_quota_exceeded`, stop until `Retry-After` (it can be hours). Otherwise honor `Retry-After`. Keep search to about 10 requests per minute for the account, not per key. Space rent calls at least 5 seconds apart. After a rent 429, look up the same `label` before you PUT again. The CLI and SDK do not read `Retry-After`. | | CLI or SDK retried a rent on its own | The CLI and SDK retry connection errors, timeouts, and HTTP 429, 502, 503, and 504. They do not read `Retry-After`. They cannot set `target_reliability`. | For an SLA rent you send yourself, set a unique `label` and look up that label before you PUT again. See [Rate limits](/cli/rate-limits). | diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 81421095..3eb64757 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -13,7 +13,7 @@ The **SLA fee** is that hourly amount. It appears as the **SLA Fee** line in the This page explains how SLA offers work from the host side — what you set, how clients choose an SLA, and what happens when uptime is good or bad. -SLA settlement is **asymmetric by design**: well above the client's target the day's credit is smaller than the SLA fee, and you keep the difference. Between the client's target and break-even (`r_be`), and at the target itself, the credit can exceed the fee. On a day at the target it is about half of that day's covered compute. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**, also needs rental history; a new machine shows "No historical data available for this machine yet"). +SLA settlement is **asymmetric by design**. Break-even (`r_be` in the [backtester](/host/sla-backtester)) is the uptime where the day's SLA fee and the renter's credit cancel out. Well above the client's target, the day's credit is smaller than the SLA fee, and you keep the difference. Between the client's target and break-even, and at the target itself, the credit can exceed the fee. On a day at the target it is about half of that day's covered compute. Charges and credits settle on a daily cadence. Preview economics with the [SLA backtester](/host/sla-backtester) (API, requires rental history) or the web console SLA preview (**Set Pricing → SLA**, also needs rental history; a new machine shows "No historical data available for this machine yet"). @@ -38,11 +38,11 @@ You set SLA in the console. Two steps still need the CLI: `vastai self-test mach ## SLA host checklist -Read [SLA in plain language](#sla-in-plain-language) before this list. +Read [SLA in plain language](#sla-in-plain-language) before this list. Check SLA access before you list: if **Set Pricing → SLA** is missing, contact support now. Approval timing varies. You can still list and test without SLA. 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. You need it for per-machine SLA earnings and, if you later unlist during an outage, for `vastai self-test machine`. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. The self-test needs its own scoped key: `machine_read`, `instance_read`, `instance_write`, and `misc` on that one key. The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. Outage recovery is in [Severe outage](#severe-outage), not in this checklist. +3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. You need it for per-machine SLA earnings and, if you later unlist during an outage, for `vastai self-test machine`. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. A full-access key is enough. If you scope the key, the self-test needs `machine_read`, `instance_read`, `instance_write`, and `misc` on that one key. See the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. Outage recovery is in [Severe outage](#severe-outage), not in this checklist. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. @@ -99,7 +99,7 @@ SLA is an optional reliability promise on **on-demand** rentals. You do not have 3. The **renter** picks a **reliability target**. You do not set their target. 4. The renter pays an **SLA fee** (a service level fee) on top of the GPU price. 5. Each day, Vast checks how long that rental was actually up. -6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. Settlement is a smooth curve around the renter's target, not a pass/fail line. Well above the target (above break-even, `r_be`), the day's credit is smaller than the SLA fee. Between the target and `r_be`, the credit can exceed the fee. At the target, the credit is about half of that day's covered compute. Further below, it approaches a full day of covered compute. The renter's **service credit** comes from your earnings. Vast holds SLA rental pay and releases it over time, so a low earnings day is not by itself a credit. Details are in [Billing vs settlement](#billing-vs-settlement-important). +6. Each day, Vast combines recent and longer-term uptime into a **blended reliability measure**. Settlement is a smooth curve around the renter's target, not a pass/fail line. Well above the target (above break-even, where the fee and the credit cancel out; `r_be` in the backtester), the day's credit is smaller than the SLA fee. Between the target and `r_be`, the credit can exceed the fee. At the target, the credit is about half of that day's covered compute. Further below, it approaches a full day of covered compute. The renter's **service credit** comes from your earnings. Vast holds SLA rental pay and releases it over time, so a low earnings day is not by itself a credit. Details are in [Billing vs settlement](#billing-vs-settlement-important). 7. One bad day can cost more than many days of fees. What this is not: @@ -688,7 +688,7 @@ Fetch the fleet once to build the work list. Before each live PUT, the loop re-r "user_id": 67890, "extended": 1, "new_contracts": [], - "upd_contracts": [1] + "upd_contracts": [2000001] } ] } diff --git a/snippets/host/cli/list-machine.mdx b/snippets/host/cli/list-machine.mdx index 47ca13a2..e278979d 100644 --- a/snippets/host/cli/list-machine.mdx +++ b/snippets/host/cli/list-machine.mdx @@ -107,7 +107,7 @@ The following options are available for all commands: | Option | Description | | --- | --- | | `--url URL` | Server REST API URL | -| `--retry N` | Retry limit | +| `--retry N` | Total attempts (default 3; use 1 for a single request; 0 sends nothing) | | `--raw` | Output machine-readable JSON | | `--explain` | Verbose explanation of API calls | | `--api-key KEY` | API key (defaults to `~/.config/vastai/vast_api_key`) | diff --git a/snippets/host/cli/self-test-machine.mdx b/snippets/host/cli/self-test-machine.mdx index 94727b4a..24fbfc85 100644 --- a/snippets/host/cli/self-test-machine.mdx +++ b/snippets/host/cli/self-test-machine.mdx @@ -45,7 +45,7 @@ The following options are available for all commands: | Option | Description | | --- | --- | | `--url URL` | Server REST API URL | -| `--retry N` | Retry limit | +| `--retry N` | Total attempts (default 3; use 1 for a single request; 0 sends nothing) | | `--raw` | Output machine-readable JSON | | `--explain` | Verbose explanation of API calls | | `--api-key KEY` | API key (defaults to `~/.config/vastai/vast_api_key`) | From 9ec5ec901a2525e8dfaa3630190aa52c370c16df Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 09:03:09 -0700 Subject: [PATCH 246/250] docs(sla): address doc-review consensus (cycle 190) A day above the host commitment can still fall below break-even, and the self-test examples use the packaged CLI. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 4 ++-- host/sla-offers.mdx | 10 +++++----- snippets/host/cli/cancel-maint.mdx | 2 +- snippets/host/cli/schedule-maint.mdx | 2 +- snippets/host/cli/self-test-machine.mdx | 15 +++++++-------- snippets/host/cli/show-maints.mdx | 2 +- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 0155ab44..5a5f8b31 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -79,7 +79,7 @@ For on-demand contracts with an SLA: - An SLA pays a **service credit**. It does not recover your data, migrate your instance, or replace the machine. Keep checkpoints and important data off the instance. - You are charged for **compute, storage, and the SLA fee** for the rental day, including periods when the instance is unavailable. - Offline time is tracked as an outage in reliability measurements. -- If you qualify for compensation, a **service credit** posts after daily settlement (UTC) — typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. +- A **service credit** for the day posts after daily settlement (UTC) — typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. SLA is most useful for **long-running production workloads** where unexpected downtime has a real cost beyond the hourly rate. @@ -379,7 +379,7 @@ During an outage the Instances price popover may say "Machine is offline. You're - **Downtime you cause:** Contact support before you count on a service credit for your own Stop or reboot, a bad image, a container crash, or a stop at zero balance. - **Final settlement:** The net SLA row still posts when the contract closes. -If you qualify for compensation, a **service credit** is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. +A **service credit** for the day is applied after daily settlement (UTC), typically within a few hours after UTC midnight for the prior day — not in the same hour as the outage. ### How reliability is measured diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 3eb64757..c2af4846 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -52,7 +52,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. Check SLA 7. **Enable SLA.** - **Do this:** In **Set Pricing → SLA**, enter **Reliability Commitment** as a percent (the field ends with `%`; type `99` for 99%). Set **Confidence**. Start at **Low** unless you have rental history. Then click **Save**. - **What Save also does:** On a machine that is already listed, **Save** publishes immediately and extends every shorter rental to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). - - **Turning SLA off later:** The console cannot set the commitment to `0`. Before you unlist, write down every **Set Pricing** field, then relist without opening the SLA controls. API users can send `"sla_r_claim": 0` instead. Active SLA contracts keep their terms either way. See [Updating SLA on an already-listed machine](#updating-sla-on-an-already-listed-machine). + - **Turning SLA off later:** The console cannot set the commitment to `0`. Before you unlist, write down every **Set Pricing** field, then relist without opening the SLA controls. A relist that sends a later end date or a duration extends shorter rentals, including SLA contracts, with no fee check. See [SLA on extended contracts](#sla-on-extended-contracts). API users can send `"sla_r_claim": 0` instead. Active SLA contracts keep their terms either way. See [Updating SLA on an already-listed machine](#updating-sla-on-an-already-listed-machine). - Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** In **Host → Machines**, confirm the machine shows **Listed**, then reopen **Set Pricing → SLA** and confirm your terms are saved. @@ -278,7 +278,7 @@ If the machine is already **listed**: 1. Open **Host → Machines → Set Pricing → SLA**, set **Reliability Commitment** and **Confidence**, then click **Save**. 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. -3. To stop offering SLA on **new** rentals, use the API. Send `"sla_r_claim": 0` in the full `create_asks` body (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). The console control cannot be set to `0`, and a **Save** that omits SLA fields keeps the current terms. **Console-only hosts:** write down every **Set Pricing** field, unlist, then relist without opening the SLA controls (see [SLA host checklist](#sla-host-checklist), step 7). Active contracts keep their locked terms until they end. +3. To stop offering SLA on **new** rentals, use the API. Send `"sla_r_claim": 0` in the full `create_asks` body (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). The console control cannot be set to `0`, and a **Save** that omits SLA fields keeps the current terms. **Console-only hosts:** write down every **Set Pricing** field, unlist, then relist without opening the SLA controls (see [SLA host checklist](#sla-host-checklist), step 7). A relist that sends a later end date or a duration extends shorter rentals, including SLA contracts, with no fee check. See [SLA on extended contracts](#sla-on-extended-contracts). Active contracts keep their locked terms until they end. 4. Verify after listing: - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. - **Search:** `dph_total` includes the SLA fee at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). @@ -759,7 +759,7 @@ Example: you publish **reliability commitment 99%**, the client chose **target 9 - A blended 97% is above a 95% target, but that is not a zero-credit day. The credit can still be larger than the SLA fee. Raw uptime alone does not decide the result. - **SLA fees** are priced from your **reliability commitment**, confidence, and the client's target — a higher reliability commitment relative to the target generally means lower client charges. -The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what drives service-credit eligibility. +The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what credits are measured against. ### If the client's target is missed @@ -782,11 +782,11 @@ Your SLA loss on a normal settlement day is tied to that day's covered compute * ### Reliability commitment 99%, delivered 99.5% -You outperform your reliability commitment. Clients who chose targets at or below 99% pay small SLA fees. Credits on those days are small. Whether you net positive depends on how far delivered reliability sits above the break-even level in the backtester. +Whether you net positive depends on the renter's target, not only on beating your commitment. Renters whose target sits well below your commitment (for example 95%) pay small SLA fees, and a 99.5% day is above break-even for that contract. Renters whose target is at or near 99% pay much higher SLA fees, and a 99.5% day can still fall below break-even (`r_be`) for that contract. Run the [SLA backtester](/host/sla-backtester) with `r_target=0.99` before you rely on this case. ### Reliability commitment 99% with an offline day -Clients receive credits tied to how far measured reliability falls below **their** target. Extended outages can approach a full-day compute credit. Your reliability score and verification status may also be affected separately from SLA settlement. +Clients receive credits tied to where the blended measure lands relative to their target. Credits start before the target is missed. Extended outages can approach a full-day compute credit. Your reliability score and verification status may also be affected separately from SLA settlement. ### Clients target near your reliability commitment diff --git a/snippets/host/cli/cancel-maint.mdx b/snippets/host/cli/cancel-maint.mdx index 07dd4820..5d4c9d9e 100644 --- a/snippets/host/cli/cancel-maint.mdx +++ b/snippets/host/cli/cancel-maint.mdx @@ -32,7 +32,7 @@ The following options are available for all commands: | Option | Description | | --- | --- | | `--url URL` | Server REST API URL | -| `--retry N` | Retry limit | +| `--retry N` | Total attempts (default 3; use 1 for a single request; 0 sends nothing) | | `--raw` | Output machine-readable JSON | | `--explain` | Verbose explanation of API calls | | `--api-key KEY` | API key (defaults to `~/.config/vastai/vast_api_key`) | diff --git a/snippets/host/cli/schedule-maint.mdx b/snippets/host/cli/schedule-maint.mdx index 47460213..46dc621c 100644 --- a/snippets/host/cli/schedule-maint.mdx +++ b/snippets/host/cli/schedule-maint.mdx @@ -80,7 +80,7 @@ The following options are available for all commands: | Option | Description | | --- | --- | | `--url URL` | Server REST API URL | -| `--retry N` | Retry limit | +| `--retry N` | Total attempts (default 3; use 1 for a single request; 0 sends nothing) | | `--raw` | Output machine-readable JSON | | `--explain` | Verbose explanation of API calls | | `--api-key KEY` | API key (defaults to `~/.config/vastai/vast_api_key`) | diff --git a/snippets/host/cli/self-test-machine.mdx b/snippets/host/cli/self-test-machine.mdx index 24fbfc85..083ef1c3 100644 --- a/snippets/host/cli/self-test-machine.mdx +++ b/snippets/host/cli/self-test-machine.mdx @@ -5,7 +5,7 @@ Perform a self-test on the specified machine ## Usage ```bash -vastai self-test machine [--debugging] [--explain] [--api_key API_KEY] [--url URL] [--retry RETRY] [--raw] [--ignore-requirements] +vastai self-test machine [--debugging] [--explain] [--api-key API_KEY] [--url URL] [--retry RETRY] [--raw] [--ignore-requirements] ``` ## Arguments @@ -21,21 +21,20 @@ vastai self-test machine [--debugging] [--explain] [--api_key API_K - Ignore the minimum system requirements and run the self test regardless + Skip later preflight checks, including offer reliability at or below 0.90. Does not bypass `currently_rented`, `zero_active_offers`, or `offline_or_not_listed`. ## Description -This command tests if a machine meets specific requirements and -runs a series of tests to ensure it's functioning correctly. +This command rents a test instance on a live offer, runs the tests, then destroys that instance. The machine must be listed. It refuses with `currently_rented`, `zero_active_offers`, or `offline_or_not_listed`. A scoped API key needs `machine_read`, `instance_read`, `instance_write`, and `misc` on that one key. ## Examples ```bash -vast self-test machine 12345 - vast self-test machine 12345 --debugging - vast self-test machine 12345 --explain - vast self-test machine 12345 --api_key +vastai self-test machine 12345 +vastai self-test machine 12345 --debugging +vastai self-test machine 12345 --explain +vastai self-test machine 12345 --api-key YOUR_API_KEY ``` ## Global Options diff --git a/snippets/host/cli/show-maints.mdx b/snippets/host/cli/show-maints.mdx index 491add21..0693cd00 100644 --- a/snippets/host/cli/show-maints.mdx +++ b/snippets/host/cli/show-maints.mdx @@ -38,7 +38,7 @@ The following options are available for all commands: | Option | Description | | --- | --- | | `--url URL` | Server REST API URL | -| `--retry N` | Retry limit | +| `--retry N` | Total attempts (default 3; use 1 for a single request; 0 sends nothing) | | `--raw` | Output machine-readable JSON | | `--explain` | Verbose explanation of API calls | | `--api-key KEY` | API key (defaults to `~/.config/vastai/vast_api_key`) | From 6dba2b71060933ede9b29ef7ac4549a9b6c86fd6 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 09:11:01 -0700 Subject: [PATCH 247/250] docs(sla): address doc-review consensus (cycle 191) Unlisting for planned work drops the SLA ask, and listing does not check the self-test for you. Co-authored-by: Cursor --- host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 8 ++++---- host/upgrade-docker-and-packages.mdx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index a54a178c..495ff23c 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -257,7 +257,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **Planned work:** schedule a [maintenance window](/host/sla-offers#scheduled-maintenance) so current renters get notice. Staying listed lets new rentals start, and a rental that starts after you schedule may not get forgiveness for that window. To block new rentals, write down **Set Pricing** and unlist ([Severe outage](/host/sla-offers#severe-outage)). +- **Planned work:** Prefer staying listed and scheduling a [maintenance window](/host/sla-offers#scheduled-maintenance) so current renters get notice. A rental that starts after you schedule may not get forgiveness for that window. If you must block new rentals, first write down every **Set Pricing** field, then unlist ([Severe outage](/host/sla-offers#severe-outage)). On an SLA machine, unlisting drops the SLA ask. The self-test cannot run while a rental is still on the machine. Listing does not check the self-test for you. Do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` A relist **Save** can extend active rentals, which pushes that date later. - **Outage, machine still online, and you need to stop new rentals:** you may unlist. Before you unlist, record every **Set Pricing** field: GPU, storage, and bandwidth prices; minimum GPUs; reserved discount (omitted on a new ask becomes `0.4`); min bid; offer end date and auto-renew duration; whether the listing is **hidden**; and **Reliability Commitment** and **Confidence**. Unlisting does not change existing rentals, but it drops the SLA ask. A blank bandwidth price publishes at $0 when you relist. When you relist, read [Severe outage step 6](/host/sla-offers#severe-outage) before choosing an end date: check the latest rental end date on **Host → Machines**, then wait until it passes or accept that shorter rentals will be extended. Pick the path that matches your situation: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index c2af4846..54ca0707 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -875,7 +875,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Console** 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). Change **Maintenance start** to a few minutes from now. The form starts 24 hours ahead. An emergency window is still unplanned, so expect full SLA exposure for it. 2. Write down every field on **Set Pricing**: GPU price, minimum GPUs, storage price, bandwidth, reserved discount, min bid, whether the listing is **hidden**, the offer end date or auto-renew duration, **Reliability Commitment**, and **Confidence**. If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. - 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. If a rental is still on the machine, SLA stays off for new rentals until that rental ends: the self-test refuses with `currently_rented`, and the relist **Save** can extend the rental. If the machine cannot take new rentals, staying listed keeps your SLA terms. + 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. If a rental is still on the machine, the self-test refuses with `currently_rented` until that rental ends. Listing does not check the self-test for you. Do not turn SLA back on until it passes. The relist **Save** can extend the rental. If the machine cannot take new rentals, staying listed keeps your SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. 6. **Return to service** only if you unlisted in step 3. @@ -911,16 +911,16 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep ``` `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). If that `include_offline` response is also empty, use the console notes above. Do not unlist until you have the terms. - 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. If a rental is still on the machine, SLA stays off for new rentals until that rental ends, because the self-test refuses with `currently_rented`. Staying listed keeps the current SLA terms. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. + 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. If a rental is still on the machine, the self-test refuses with `currently_rented` until that rental ends. Listing does not check the self-test for you. Do not turn SLA back on until it passes. Staying listed keeps the current SLA terms. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. 6. **Return to service.** a. **First PUT, without SLA.** Relisting creates a new ask, so stored values do not carry over. Send `price_gpu`, `price_disk`, `price_inetu`, `price_inetd`, `min_chunk`, `end_date` or `duration` (not both; `duration` as an integer), `hidden_listing`, `credit_discount_max`, `price_min_bid`, `"vol_size": 0` unless you want a volume offer, and `"sla_r_claim": 0`. An omitted `credit_discount_max` becomes `0.4`. No documented API shows each rental's end date. Check **Host → Machines** before you choose `end_date` or `duration`. Sending either extends every active rental that ends sooner. If the machine stays locked, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai before you relist. - b. **Self-test.** Run `vastai self-test machine MACHINE_ID`. Use the same three outcomes as the console step. If it refuses to start, leave SLA off until the rental ends or the reliability score recovers. That wait can last as long as the extended contract. + b. **Self-test.** Run `vastai self-test machine MACHINE_ID`. Use the same three outcomes as the console step. If it refuses to start, do not send SLA terms yet. Listing does not check the self-test for you. Waiting until the rental ends or the reliability score recovers can last as long as the extended contract. - c. **Second PUT, with SLA.** Only after the last line is `Test completed successfully.`, send the full body from [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body): `price_disk`, `price_inetu`, `price_inetd`, `credit_discount_max`, `min_chunk`, `hidden_listing`, `"vol_size": 0`, plus `sla_r_claim` and `sla_sigma_x` from your notes. Omitting those listing fields resets them (`price_disk` goes back to $0.10, a hidden listing becomes public, and a missing `vol_size` can create a volume offer). On a fixed end date, omit `end_date` and `duration` so no rental is extended again. On a rolling listing, omitting `duration` turns auto-renew off. Resend the same integer `duration` if you want auto-renew to stay on. That duration is measured from now, so this second request can extend shorter rentals a bit further than the first. + c. **Second PUT, with SLA.** The PUT does not check for a passing self-test. Only after the last line is `Test completed successfully.`, send the full body from [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body): `price_disk`, `price_inetu`, `price_inetd`, `credit_discount_max`, `min_chunk`, `hidden_listing`, `"vol_size": 0`, plus `sla_r_claim` and `sla_sigma_x` from your notes. Omitting those listing fields resets them (`price_disk` goes back to $0.10, a hidden listing becomes public, and a missing `vol_size` can create a volume offer). On a fixed end date, omit `end_date` and `duration` so no rental is extended again. On a rolling listing, omitting `duration` turns auto-renew off. Resend the same integer `duration` if you want auto-renew to stay on. That duration is measured from now, so this second request can extend shorter rentals a bit further than the first. ## Monitoring SLA after listing diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index a5625577..bf3d83ab 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -535,7 +535,7 @@ Canceled hold on linux-image-generic-hwe-24.04. ### Relist -Relist from the [Machines page](https://cloud.vast.ai/host/machines/). Re-enter every **Set Pricing** field you wrote down. If the machine had an SLA, relist **without** opening the SLA controls: in **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. A relist after an unlist creates a new offer without SLA. Run the self-test below. Only after it passes, open **Set Pricing → SLA**, re-enter your terms, and click **Save**. If the self-test fails, unlist right away. `vastai list machine` creates the ask without SLA and can reset bandwidth and other fields. See the [`list machine` cautions](/host/cli/list-machine). After 2 to 3 +Relist from the [Machines page](https://cloud.vast.ai/host/machines/). Re-enter every **Set Pricing** field you wrote down. If the machine had an SLA, relist **without** opening the SLA controls: in **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. A relist after an unlist creates a new offer without SLA. Run the self-test below. Listing does not check the self-test for you. Only after it passes, open **Set Pricing → SLA**, re-enter your terms, and click **Save**. If the self-test fails, unlist right away. `vastai list machine` creates the ask without SLA and can reset bandwidth and other fields. See the [`list machine` cautions](/host/cli/list-machine). After 2 to 3 minutes: ```bash From 57c151a147d89dff0571300f0e9fbe05db943df7 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 09:20:05 -0700 Subject: [PATCH 248/250] docs(sla): address doc-review consensus (cycle 192) The host checklist no longer repeats the scoped-key list, and a host-key search is not treated as proof that renters can see the offer. Co-authored-by: Cursor --- api-reference/permissions.mdx | 2 +- cli/reference/search-offers.mdx | 2 +- guides/instances/choosing/sla-coverage.mdx | 1 + host/hosting-overview.mdx | 2 +- host/sla-offers.mdx | 6 +++--- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/api-reference/permissions.mdx b/api-reference/permissions.mdx index a61f9718..6b43f138 100644 --- a/api-reference/permissions.mdx +++ b/api-reference/permissions.mdx @@ -188,7 +188,7 @@ Create the key via [Create API Key](/api-reference/accounts/create-api-key). Do | Confirm windows (`vastai show maints`) | `instance_read` | **Machine Maintenances** or **Scheduled Maintenances**. | | Run `vastai self-test machine` | `machine_read`, `instance_read`, `instance_write`, and `misc` (offer search), on one key | The command rents and then destroys a test instance. | | Monitor `sla_earn` | `billing_read` | Host → Billing / Earnings (console billing needs no API key; API earnings need `billing_read`). Use `per_machine[].sla_earn` for one machine; `per_day[].sla_earn` is fleet-wide even with `machid`. See [Monitoring SLA after listing](/host/sla-offers#monitoring-sla-after-listing). | -| Verify the listing in search | `misc` (separate key) | **Host → Machines** (no API key). Optional CLI: `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10` (`verified=any` is often required when checking your own machine). | +| Verify the listing in search | `misc` on the **host** account shows that the ask exists. It does not prove renters can see it. Use a key from a separate client account for that. | **Host → Machines** (no API key). Client-account check: [SLA host checklist step 8](/host/sla-offers#sla-host-checklist). | Earnings URL: `GET /api/v0/users/me/machine-earnings/`. The path user id is ignored; the API key owner is used, so do not add `user_read` just to discover an id. Start with [SLA in plain language](/host/sla-offers#sla-in-plain-language). diff --git a/cli/reference/search-offers.mdx b/cli/reference/search-offers.mdx index 36f92959..1e8e2ff9 100644 --- a/cli/reference/search-offers.mdx +++ b/cli/reference/search-offers.mdx @@ -191,7 +191,7 @@ bool = True | False | `verified` | bool | is the machine verified | | `vms_enabled` | bool | is the machine a VM instance | -**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability`. The CLI cannot send it: a query string becomes `{"eq": …}` and returns HTTP 400, so CLI `--raw` output has no SLA fee. The `VastAI` client can, if you pass a dict such as `search_offers(query={"has_sla": {"eq": True}, "target_reliability": 0.95}, storage=50)`. `SyncClient.search` (and `AsyncClient.search`) can also quote an SLA with `target_reliability` as a plain number. Neither client can enable SLA at rent: `create_instance()` and `InstanceConfig` have no `target_reliability`. `SyncClient` and `AsyncClient` do not retry. Pass the same `storage` you will rent. The SDK default is 5 GiB, which changes `dph_total`. The SDK returns only the offers list. `truncated` is visible only via REST. A string query fails the same way as the CLI. `search_offers()` cannot rent with SLA. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. +**SLA query keys:** `has_sla`, `expected_reliability`, `target_reliability`. `dph_total` and `search.slaPremiumPerHour` include the SLA fee only when the search set `target_reliability`. The CLI cannot send it: a query string becomes `{"eq": …}` and returns HTTP 400, so CLI `--raw` output has no SLA fee. The `VastAI` client can, if you pass a dict such as `search_offers(query={"has_sla": {"eq": True}, "target_reliability": 0.95}, storage=50)`. `SyncClient.search` (and `AsyncClient.search`) can also quote an SLA with `target_reliability` as a plain number. Neither client can enable SLA at rent: `create_instance()` and `InstanceConfig` have no `target_reliability`. `SyncClient` and `AsyncClient` do not retry. Pass the same `storage` you will rent. The SDK default is 5 GiB, which changes `dph_total`. The SDK returns only the offers list. `truncated` is visible only via REST. When it is true, the server cut the result short of `limit`. Narrow the query instead of assuming you saw every offer. A string query fails the same way as the CLI. `search_offers()` cannot rent with SLA. `dph_total` (alias `dph`) is also a CLI query filter, and that filter compares the price **without** the SLA fee. | Field | Meaning | | --- | --- | diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 5a5f8b31..7a2f0abb 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -332,6 +332,7 @@ A timeout, a dropped connection, or HTTP 5xx means the rental may already exist. | Offer has no SLA, target is above the host commitment, or the SLA fee would exceed 1× compute | HTTP 400 `invalid_sla_params` (body includes `ask_id`; message may say "SLA Fee would be N.NNx compute") | Lower the target, or pick an offer with a higher commitment | | SLA not available | HTTP 403 `sla_disabled` | SLA is not enabled. This is a single platform-wide switch, not an account or region setting. Do not retry in a loop. Rent without a reliability target, or contact support. | | Offer no longer exists | HTTP 400 `invalid_args` (`msg` may contain `error 404/3603`), HTTP 404 `no_such_ask` (`msg` may contain `error 404/3659` if the offer was taken mid-request), or HTTP 410 | Re-search and use a fresh offer ID. Do not retry the same ID. | +| GPU price above the platform maximum | HTTP 400 `invalid_price` | Not caused by `target_reliability`. Re-search and rent a fresh offer ID. Do not retry the same ID. | | Ask cannot start now (`cancel_unavail`) | HTTP 410, error `no_such_ask` | Search for a new offer; this is not a transient glitch to retry on the same id | | `price` (bid) sent together with `target_reliability` | HTTP 400 `invalid_args`: "Cannot combine interruptible instances with SLAs" | Remove `price`. SLA rentals are on-demand only | | Timeout, dropped connection, or HTTP 5xx | Outcome unknown — the rental may already exist | See [If the rent outcome is unknown](#if-the-rent-outcome-is-unknown). | diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 495ff23c..76c0d450 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -257,7 +257,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **Planned work:** Prefer staying listed and scheduling a [maintenance window](/host/sla-offers#scheduled-maintenance) so current renters get notice. A rental that starts after you schedule may not get forgiveness for that window. If you must block new rentals, first write down every **Set Pricing** field, then unlist ([Severe outage](/host/sla-offers#severe-outage)). On an SLA machine, unlisting drops the SLA ask. The self-test cannot run while a rental is still on the machine. Listing does not check the self-test for you. Do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` A relist **Save** can extend active rentals, which pushes that date later. +- **Planned work:** Prefer staying listed and scheduling a [maintenance window](/host/sla-offers#scheduled-maintenance) so current renters get notice. A rental that starts after you schedule may not get forgiveness for that window. If you must block new rentals, first write down every **Set Pricing** field, then unlist ([Severe outage](/host/sla-offers#severe-outage)). On an SLA machine, unlisting drops the SLA ask. The self-test cannot run while a rental is still on the machine. Listing does not check the self-test for you. Do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` A relist **Save** can extend active rentals, which pushes the latest rental end date later. - **Outage, machine still online, and you need to stop new rentals:** you may unlist. Before you unlist, record every **Set Pricing** field: GPU, storage, and bandwidth prices; minimum GPUs; reserved discount (omitted on a new ask becomes `0.4`); min bid; offer end date and auto-renew duration; whether the listing is **hidden**; and **Reliability Commitment** and **Confidence**. Unlisting does not change existing rentals, but it drops the SLA ask. A blank bandwidth price publishes at $0 when you relist. When you relist, read [Severe outage step 6](/host/sla-offers#severe-outage) before choosing an end date: check the latest rental end date on **Host → Machines**, then wait until it passes or accept that shorter rentals will be extended. Pick the path that matches your situation: diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 54ca0707..2cb09241 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -25,7 +25,7 @@ SLA settlement is **asymmetric by design**. Break-even (`r_be` in the [backteste Not listed yet? Finish [machine setup](/host/hosting-overview#machine-setup) and the [host setup guide](https://cloud.vast.ai/host/setup/) before you enable an SLA. -You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. Outage recovery, including when to turn SLA back on, is in [Severe outage](#severe-outage). A full-access key covers this page. `vastai self-test machine` searches offers, then rents and destroys a test instance. If you use a scoped key for it, that one key needs `machine_read`, `instance_read`, `instance_write`, and `misc`. The listing key in the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe) cannot run the self-test. +You set SLA in the console. Two steps still need the CLI: `vastai self-test machine` after you unlist during an outage, and per-machine SLA earnings (`vastai show earnings`). Install the CLI before you enable SLA. Outage recovery, including when to turn SLA back on, is in [Severe outage](#severe-outage). A full-access key covers both CLI steps. For a scoped key, use the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). The listing key on that page cannot run the self-test. | Goal | Start here | @@ -42,7 +42,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. Check SLA 1. Complete [Account setup and hosting agreement](/host/hosting-overview#account-setup-and-hosting-agreement) on a **dedicated host account**, then [host setup](https://cloud.vast.ai/host/setup/). Confirm the machine appears on **Host → Machines** (healthy; GPU price and offer end date saved under **Set Pricing**). Listing happens in step 2. If the listing uses auto-renew, read [SLA on extended contracts](#sla-on-extended-contracts) before you enable SLA. 2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. -3. Install the [CLI](/cli/hello-world) and create an API key before step 7, even if you manage the machine in the console. You need it for per-machine SLA earnings and, if you later unlist during an outage, for `vastai self-test machine`. **Host → Billing** is fleet-wide and has no per-machine SLA line. `vastai show earnings --machine_id ID` needs an API key with `billing_read`. A full-access key is enough. If you scope the key, the self-test needs `machine_read`, `instance_read`, `instance_write`, and `misc` on that one key. See the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). The console [Set a maintenance window](/host/set-maintenance-window) page can notify renters without the CLI. Outage recovery is in [Severe outage](#severe-outage), not in this checklist. +3. **Install the [CLI](/cli/hello-world) and create an API key** before step 7, even if you use the console. You need it for `vastai show earnings` and, after an unlist, for `vastai self-test machine`. A full-access key is enough. Scoped keys are in the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). Outage recovery is in [Severe outage](#severe-outage), not in this checklist. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. @@ -52,7 +52,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. Check SLA 7. **Enable SLA.** - **Do this:** In **Set Pricing → SLA**, enter **Reliability Commitment** as a percent (the field ends with `%`; type `99` for 99%). Set **Confidence**. Start at **Low** unless you have rental history. Then click **Save**. - **What Save also does:** On a machine that is already listed, **Save** publishes immediately and extends every shorter rental to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). - - **Turning SLA off later:** The console cannot set the commitment to `0`. Before you unlist, write down every **Set Pricing** field, then relist without opening the SLA controls. A relist that sends a later end date or a duration extends shorter rentals, including SLA contracts, with no fee check. See [SLA on extended contracts](#sla-on-extended-contracts). API users can send `"sla_r_claim": 0` instead. Active SLA contracts keep their terms either way. See [Updating SLA on an already-listed machine](#updating-sla-on-an-already-listed-machine). + - **Turning SLA off later:** see [Updating SLA on an already-listed machine](#updating-sla-on-an-already-listed-machine). Unlisting and relisting can extend shorter SLA contracts. - Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). 8. **Verify now.** In **Host → Machines**, confirm the machine shows **Listed**, then reopen **Set Pricing → SLA** and confirm your terms are saved. From 95f7c766d9c29909c4e6e4ff509753cf6b6ee746 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 09:28:09 -0700 Subject: [PATCH 249/250] docs(sla): address doc-review consensus (cycle 193) Turning SLA off points at the relist step, and cancel maint documents the admin_locked count the API returns. Co-authored-by: Cursor --- api-reference/openapi.yaml | 7 ++++++- api-reference/openapi/yaml/cancel_maint.yaml | 6 +++++- guides/instances/choosing/find-and-rent.mdx | 2 +- host/sla-backtester.mdx | 2 +- host/sla-offers.mdx | 19 +++++++++---------- host/upgrade-docker-and-packages.mdx | 3 +-- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 045543eb..1ce0f2fb 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -298,7 +298,8 @@ paths: /api/v0/machines/{machine_id}/cancel_maint: put: summary: cancel maint - description: 'Cancel a scheduled maintenance window for a specified machine. + description: 'Cancel every host-scheduled maintenance window on a machine. Vast-scheduled + windows are left in place. CLI Usage: `vastai cancel maint `' @@ -331,6 +332,10 @@ paths: type: string example: deleted 1 scheduled maintenance window(s) on machine 1234 + admin_locked: + type: integer + description: Number of Vast-scheduled windows left in place. + example: 0 '404': description: Machine not found or does not belong to the user. content: diff --git a/api-reference/openapi/yaml/cancel_maint.yaml b/api-reference/openapi/yaml/cancel_maint.yaml index ae2df1c8..c7f881d4 100644 --- a/api-reference/openapi/yaml/cancel_maint.yaml +++ b/api-reference/openapi/yaml/cancel_maint.yaml @@ -7,7 +7,7 @@ paths: put: summary: cancel maint description: | - Cancel a scheduled maintenance window for a specified machine. + Cancel every host-scheduled maintenance window on a machine. Vast-scheduled windows are left in place. CLI Usage: `vastai cancel maint ` parameters: @@ -39,6 +39,10 @@ paths: type: string example: deleted 1 scheduled maintenance window(s) on machine 1234 + admin_locked: + type: integer + description: Number of Vast-scheduled windows left in place. + example: 0 '404': description: Machine not found or does not belong to the user. content: diff --git a/guides/instances/choosing/find-and-rent.mdx b/guides/instances/choosing/find-and-rent.mdx index d742ceb7..bb8c60df 100644 --- a/guides/instances/choosing/find-and-rent.mdx +++ b/guides/instances/choosing/find-and-rent.mdx @@ -87,7 +87,7 @@ Click on the "Change Template" button to bring up the template config menu that ![Edit](/images/find-and-rent-edit.webp) -Some offers include an optional **SLA** reliability commitment. It pays a service credit when uptime falls short. It does not keep the machine up. To filter and compare SLA-backed rentals, see [SLA](/guides/instances/choosing/sla-coverage). +Some offers include an optional **SLA** reliability commitment. It pays a daily service credit that grows as measured uptime falls toward and below your target. It does not keep the machine up. To filter and compare SLA-backed rentals, see [SLA](/guides/instances/choosing/sla-coverage). ## Common Questions diff --git a/host/sla-backtester.mdx b/host/sla-backtester.mdx index 57800a56..8bb6550d 100644 --- a/host/sla-backtester.mdx +++ b/host/sla-backtester.mdx @@ -253,7 +253,7 @@ The two values are exactly related: `p = 1 / (1 + sla_sigma_x)`, and `sla_sigma_ | `0.6667` | Medium (default) | Normal | `sla_sigma_x ≈ 0.5` | | `0.50` | Low | Wide | `sla_sigma_x ≈ 1.0` | -Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** reduce the credit owed on a miss. +Tighter confidence (higher `p`) lowers the SLA fee renters pay. It does **not** reduce the credit owed on a low-reliability day. ## Error responses diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 2cb09241..609b5d1f 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -44,17 +44,16 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. Check SLA 2. Publish once **without** SLA. In **Set Pricing**, leave the SLA controls closed, click **Save**, then **LIST**. The console cannot set **Reliability Commitment** to `0`. If you do not see an SLA section, list without it. Step 4 is where you check SLA access. Test ports, SSH, and Jupyter from a separate client account (see [Testing your own machine](/host/hosting-overview#testing-your-own-machine)). **Destroy** that test instance before step 7. A running or stopped test rental is extended to the listing end date when you click **Save**. Do not turn SLA on until that test passes. 3. **Install the [CLI](/cli/hello-world) and create an API key** before step 7, even if you use the console. You need it for `vastai show earnings` and, after an unlist, for `vastai self-test machine`. A full-access key is enough. Scoped keys are in the [host SLA recipe](/api-reference/permissions#host-sla-scoped-key-recipe). Outage recovery is in [Severe outage](#severe-outage), not in this checklist. 4. Confirm SLA account access: open **Set Pricing → SLA** and confirm the panel is visible (do **not** Save final commitment/confidence yet). If **Set Pricing** has no **SLA** section, contact support before you enable SLA. A missing section is not a fee preview. - - **API users:** `PUT /api/v0/machines/create_asks/` returns 403 `sla_not_approved` when the host is not approved. 5. Preview economics only if the machine already has rental history (console SLA panel or [backtester](/host/sla-backtester)). On a new machine, neither can show a number yet. Start at **Low** confidence, use the [economics walkthrough](#economics-walkthrough) as your estimate, and confirm the real fee in step 8 after you save. Read [Billing vs settlement](#billing-vs-settlement-important) and [Risk scenarios](#risk-scenarios). GPU billing can continue during outages, and SLA credits can exceed many days of SLA fees. - **All hosts:** After you enable SLA, GPU earnings in **Host → Billing** can drop. That compute is paid out later as SLA earnings, and much of it can stay held until the contract ends. A lower total is not by itself a credit. - - **API users:** Read daily SLA releases as `per_machine[].sla_earn`. This is money released to you that day, not the amount still held. See [Monitoring SLA after listing](#monitoring-sla-after-listing). 6. Read [Scheduled maintenance](#scheduled-maintenance) before you turn SLA on. Turn on **Account Settings → Notification Settings** (Host group) for `host:machine_offline` and `host:machine_error` ([Host Notifications](/host/notifications)) so you hear about downtime before next-day settlement. Schedule planned work as far ahead as you can. Some hosts assume 24 hours of notice fully forgives the downtime. It does not, and forgiveness is not guaranteed. 7. **Enable SLA.** - **Do this:** In **Set Pricing → SLA**, enter **Reliability Commitment** as a percent (the field ends with `%`; type `99` for 99%). Set **Confidence**. Start at **Low** unless you have rental history. Then click **Save**. - **What Save also does:** On a machine that is already listed, **Save** publishes immediately and extends every shorter rental to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). - **Turning SLA off later:** see [Updating SLA on an already-listed machine](#updating-sla-on-an-already-listed-machine). Unlisting and relisting can extend shorter SLA contracts. - Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. - - **API users:** send `sla_r_claim` as a fraction (`0.99`, not `99`). After **Save**, run the confidence check in [Validation rules](#validation-rules). +**API users:** `sla_not_approved`, daily `per_machine[].sla_earn`, and `sla_r_claim` as a fraction (`0.99`, not `99`) are under [API (for automation)](#api-for-automation). + 8. **Verify now.** In **Host → Machines**, confirm the machine shows **Listed**, then reopen **Set Pricing → SLA** and confirm your terms are saved. - **CLI:** search from a separate client account ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)): `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. The CLI cannot send `target_reliability`, so its `dph_total` does **not** include the SLA fee and it never shows an **SLA Fee** line. An empty result can also mean every GPU is rented or the listing is hidden. - **SLA fee:** check it in the console from that same client account (**Search → Reliability target**), then confirm the **SLA Fee** line on your offer. A REST search that sends `target_reliability` also returns the fee-inclusive `dph_total`. If the console shows no **SLA Fee** line at a target at or below your commitment, contact support. Optionally rent that offer briefly, then **Destroy** the test instance. @@ -130,10 +129,10 @@ Think of an SLA offer as two host ideas plus one client choice: When a client rents an on-demand instance on your SLA-listed offer with a chosen target: -- While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA fee** — including during downtime. Settlement credits for missed targets are calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA fee at the quoted allocation — **not** bandwidth. +- While a rental **contract** is active, clients pay GPU, storage, bandwidth (usage-based), and a **small hourly SLA fee** — including during downtime. The daily service credit follows a smooth curve and is calculated separately at UTC day boundaries. In search results, **`dph_total`** is the quoted hourly rental cost: GPU + storage + SLA fee at the quoted allocation — **not** bandwidth. - Each UTC calendar day, Vast measures reliability for the contract and settles the SLA. - **Well above the client's target** (above break-even) → the day's credit is smaller than the SLA fee, and you keep the difference. -- **Shortfalls** → credits flow to the client from your earnings. On a normal day, the credit can be as large as that day's rental charges for the contract. See [SLA and GPU slicing](#sla-and-gpu-slicing) for the last-day caveat. +- **Lower blended reliability** → larger credits flow to the client from your earnings. On a normal day, the credit can be as large as that day's rental charges for the contract. See [SLA and GPU slicing](#sla-and-gpu-slicing) for the last-day caveat. Over many strong days, SLA fees can offset occasional credits, but a single bad day can exceed months of collected SLA fees — see [Risk scenarios](#risk-scenarios) and the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) before you commit. @@ -206,7 +205,7 @@ In the console, pick **High**, **Medium**, or **Low**. High is a tight margin (s **Never copy backtester `p` into `sla_sigma_x` — the scales are inverted.** See the full mapping on the [backtester page](/host/sla-backtester#confidence-values-p). -**High** (tight margin) → lower client SLA fees (more competitive `dph_total`) and less fee income to offset a miss. **Low** (wide margin) → higher client SLA fees, which is a cushion, not a smaller credit. For a new or volatile machine, start with **Low**, then move to **Medium** once uptime is stable. Confidence does **not** change the credit formula when a target is missed — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. +**High** (tight margin) → lower client SLA fees (more competitive `dph_total`) and less fee income to offset a low-reliability day. **Low** (wide margin) → higher client SLA fees, which is a cushion, not a smaller credit. For a new or volatile machine, start with **Low**, then move to **Medium** once uptime is stable. Confidence does **not** change the credit on a low-reliability day — use the backtester's [largest single-day credit](/host/sla-backtester#summarize-with-jq) and `r_target` what-ifs for tail-risk planning. ### Validation rules @@ -278,7 +277,7 @@ If the machine is already **listed**: 1. Open **Host → Machines → Set Pricing → SLA**, set **Reliability Commitment** and **Confidence**, then click **Save**. 2. **Save** applies SLA to the live offer — you do not need to click **LIST** again unless this is a brand-new listing that was never published. -3. To stop offering SLA on **new** rentals, use the API. Send `"sla_r_claim": 0` in the full `create_asks` body (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). The console control cannot be set to `0`, and a **Save** that omits SLA fields keeps the current terms. **Console-only hosts:** write down every **Set Pricing** field, unlist, then relist without opening the SLA controls (see [SLA host checklist](#sla-host-checklist), step 7). A relist that sends a later end date or a duration extends shorter rentals, including SLA contracts, with no fee check. See [SLA on extended contracts](#sla-on-extended-contracts). Active contracts keep their locked terms until they end. +3. To stop offering SLA on **new** rentals, use the API. Send `"sla_r_claim": 0` in the full `create_asks` body (see [Update SLA on an existing ask](#update-sla-on-an-existing-ask-partial-body)). The console control cannot be set to `0`, and a **Save** that omits SLA fields keeps the current terms. **Console-only hosts:** write down every **Set Pricing** field, unlist, then relist without opening the SLA controls (see [SLA host checklist](#sla-host-checklist), step 2: leave the SLA controls closed, then **Save** and **LIST**). A relist that sends a later end date or a duration extends shorter rentals, including SLA contracts, with no fee check. See [SLA on extended contracts](#sla-on-extended-contracts). Active contracts keep their locked terms until they end. 4. Verify after listing: - **Console:** confirm the machine status is **Listed**, reopen **Set Pricing → SLA** to review the preview, or check offer details under **Host → Machines**. - **Search:** `dph_total` includes the SLA fee at a client's `target_reliability`, and `expected_reliability` matches your reliability commitment (see [Search / client-visible fields](#search--client-visible-fields)). @@ -761,7 +760,7 @@ Example: you publish **reliability commitment 99%**, the client chose **target 9 The **reliability commitment** is your belief and pricing knob. The client's **reliability target** is what credits are measured against. -### If the client's target is missed +### When blended reliability is at or below the client's target A single bad day can wipe out weeks or months of SLA fees. In this example, a day that lands on the renter's target costs about half of that day's covered compute (on the order of the −$42 row), not one day's SLA fee. A day a point or two below costs more than that. A full outage day is on the order of a full day of compute (the −$84 row). These figures are illustrative. Use **Set Pricing → SLA** or the backtester for your machine. Review the economics below before enabling SLA. @@ -844,7 +843,7 @@ curl -s -X PUT "https://console.vast.ai/api/v0/machines/${MACHINE_ID}/dnotify" \ `sdate` is Unix epoch seconds (UTC). Use a future time. For an outage already underway, one minute from now is enough. `duration` is whole hours. `maintenance_category` is one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. The server stores `maintenance_reason` as empty. Each planned downtime should have exactly one window. A machine may have several windows for different downtimes. In scripts, pass `--retry 1`. A retried PUT can create a second window if the first was stored and the response was lost. Confirm the count before you schedule the next machine. -**Cancel or reschedule:** The command asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the list is empty of your windows before you schedule the replacement. `cancel maint` does not cancel windows that Vast scheduled. In `show maints --raw` those rows have `admin_scheduled: true`. The cancel response reports how many it left in place as `admin_locked` (a count). See [Schedule Maintenance](/api-reference/machines/schedule-maint). +**Cancel or reschedule:** The command asks `Continue? [y/n]`. In scripts, use `echo y | vastai cancel maint MACHINE_ID`, or call `PUT /api/v0/machines/{id}/cancel_maint/` directly. Confirm the list is empty of your windows before you schedule the replacement. `cancel maint` does not cancel windows that Vast scheduled. In `show maints --raw` those rows have `admin_scheduled: true`. The cancel response includes `admin_locked`, a count of Vast-scheduled windows left in place, and `msg` reports how many host windows were deleted. See [Cancel Maintenance](/api-reference/machines/cancel-maint). **Emergency or unplanned downtime:** Notify clients if possible using `schedule maint`, but expect **full SLA settlement exposure**. Advance-notice forgiveness does not apply to unplanned outages. @@ -1015,7 +1014,7 @@ When you pass `machid`, use `per_machine[].sla_earn` for that machine's SLA sett #### Daily per-machine record -Call earnings once per UTC day (`sday=eday=D`, no `machid`) for each of the last 7 days, at least 2 seconds apart, and compare `per_machine[].sla_earn` with the value you stored for that machine and day. The backtester is not a per-day audit of `sla_earn`. The two match only when the machine's only rental that day was a single SLA contract at the simulated target. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover, not as a match to one settled UTC calendar day. +Call earnings once per UTC day (`sday=eday=D`, no `machid`) for each of the last 7 days, at least 2 seconds apart, and compare `per_machine[].sla_earn` with the value you stored for that machine and day. The backtester is not a per-day audit of `sla_earn`. Do not expect the two to match. The backtester replays GPU, storage, and bandwidth earnings, and SLA-contract compute is stored separately, so a day that already had SLA rentals cannot be reproduced as `sla_earn`. Use `sla_earn` for what was settled and the backtester only to preview terms. See [Simulation limits](/host/sla-backtester#simulation-limits). Never compare `sla_earn` with the largest single-day credit (`escrow_to_client_balance`). Use `last_days=1` with `machid` only for coarse polling after UTC rollover, not as a match to one settled UTC calendar day. ```bash # Fleet daily record: omit machid. Illustrative only — add HTTP 429 backoff at fleet scale. diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index bf3d83ab..82535abd 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -125,8 +125,7 @@ openssh-server/noble-updates 1:9.6p1-3ubuntu13.14 amd64 [upgradable from: 1:9.6p ... ``` -Empty list and Docker already current: nothing to upgrade. -**Relist and stop here.** +Empty list and Docker already current: nothing to upgrade. Relist using [Relist](#relist) and stop here. On an SLA machine, follow that order: relist without opening the SLA controls, run the [self-test](#self-test), and turn SLA back on only after `Test completed successfully.` Listing does not check the self-test for you. List the packages the daemon holds. Everything here gets upgraded: From ecc1b82fd550287b5e006175039a1ddc6a39aef7 Mon Sep 17 00:00:00 2001 From: rfernandez Date: Fri, 9 Oct 2026 10:05:13 -0700 Subject: [PATCH 250/250] docs(sla): address doc-review consensus (cycle 194) Maintenance forgiveness follows the window, not when a rental started, and the self-test can still run when a sliced machine has a rentable offer. Co-authored-by: Cursor --- guides/instances/choosing/sla-coverage.mdx | 2 +- host/hosting-overview.mdx | 2 +- host/set-maintenance-window.mdx | 2 +- host/sla-offers.mdx | 11 +++++------ host/upgrade-docker-and-packages.mdx | 2 +- snippets/host/cli/self-test-machine.mdx | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/guides/instances/choosing/sla-coverage.mdx b/guides/instances/choosing/sla-coverage.mdx index 7a2f0abb..80e9d502 100644 --- a/guides/instances/choosing/sla-coverage.mdx +++ b/guides/instances/choosing/sla-coverage.mdx @@ -38,7 +38,7 @@ Before you start: ensure [Account → Billing](https://cloud.vast.ai/billing/) h 3. Set the instance disk size on the slider (console default is 10 GB). If you are comparing against a CLI or REST quote, use the same disk size so the prices match. 4. Hover over the offer's price and confirm an **SLA Fee** line, then click **RENT**. That line means this offer will be rented with an SLA at your target. If an offer shows no **SLA Fee** line, renting it gives you no SLA. 5. Once the instance shows **running**, open **Instances** → **price details** and confirm an **SLA Fee** line. The line is hidden while the instance is loading, stopped, or offline. -6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), open **Account → Billing → Charges** (not Invoices). Each UTC day has one net SLA row: the fee minus any service credit. If the credit is larger than the fee, the row is **Service Credit** (`+$`). Otherwise it is **SLA Fee** (`−$`), and that row can still include a partial credit. You cannot see measured reliability, and you cannot split the fee from the credit. If a day had an outage and you need to know whether a credit was applied, contact support with the instance ID and the UTC date. +6. After the prior UTC day has settled (credits usually appear hours after UTC midnight; see [Settlement timing](#settlement-timing)), open **Account → Billing → Charges** (not Invoices). Each UTC day has one net SLA row: the fee minus any service credit. The **SLA Fee** label on that row is the day's net, not the hourly **SLA Fee** line in the price breakdown. If the credit is larger than the fee, the row is **Service Credit** (`+$`). Otherwise it is **SLA Fee** (`−$`), and that row can still include a partial credit. You cannot see measured reliability, and you cannot split the fee from the credit. If a day had an outage and you need to know whether a credit was applied, contact support with the instance ID and the UTC date. 7. When you are done, **Destroy** the instance to end the rental. Destroy deletes the disk. Do not assume **Stop** ends SLA charges. See [Stop vs destroy](#what-you-pay-during-an-outage). **If you used the CLI to search:** set **Reliability target** again in the console **Search filters** (left bar) before you click **RENT**. CLI filters do not carry over. diff --git a/host/hosting-overview.mdx b/host/hosting-overview.mdx index 76c0d450..275ae7ba 100644 --- a/host/hosting-overview.mdx +++ b/host/hosting-overview.mdx @@ -257,7 +257,7 @@ Remember that a single machine may have multiple active rental contracts from di Unlisting the offer prevents new rentals but does not end existing ones. -- **Planned work:** Prefer staying listed and scheduling a [maintenance window](/host/sla-offers#scheduled-maintenance) so current renters get notice. A rental that starts after you schedule may not get forgiveness for that window. If you must block new rentals, first write down every **Set Pricing** field, then unlist ([Severe outage](/host/sla-offers#severe-outage)). On an SLA machine, unlisting drops the SLA ask. The self-test cannot run while a rental is still on the machine. Listing does not check the self-test for you. Do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` A relist **Save** can extend active rentals, which pushes the latest rental end date later. +- **Planned work:** Prefer staying listed and scheduling a [maintenance window](/host/sla-offers#scheduled-maintenance) so current renters get notice. Forgiveness is per machine. It depends on how far ahead you scheduled the window and how long the window is, not on when a rental started. Schedule as early as you can. If you must block new rentals, first write down every **Set Pricing** field, then unlist ([Severe outage](/host/sla-offers#severe-outage)). On an SLA machine, unlisting drops the SLA ask. The self-test can still run if the machine has a rentable offer. It refuses with `currently_rented` only when it finds no rentable offer and at least one offer is already rented. Listing does not check the self-test for you. Do not turn SLA back on until `vastai self-test machine` prints `Test completed successfully.` A relist **Save** can extend active rentals, which pushes the latest rental end date later. - **Outage, machine still online, and you need to stop new rentals:** you may unlist. Before you unlist, record every **Set Pricing** field: GPU, storage, and bandwidth prices; minimum GPUs; reserved discount (omitted on a new ask becomes `0.4`); min bid; offer end date and auto-renew duration; whether the listing is **hidden**; and **Reliability Commitment** and **Confidence**. Unlisting does not change existing rentals, but it drops the SLA ask. A blank bandwidth price publishes at $0 when you relist. When you relist, read [Severe outage step 6](/host/sla-offers#severe-outage) before choosing an end date: check the latest rental end date on **Host → Machines**, then wait until it passes or accept that shorter rentals will be extended. Pick the path that matches your situation: diff --git a/host/set-maintenance-window.mdx b/host/set-maintenance-window.mdx index be027e41..d8a44297 100644 --- a/host/set-maintenance-window.mdx +++ b/host/set-maintenance-window.mdx @@ -13,7 +13,7 @@ unlist the machine, or block new rentals. You still take the machine down yourse when the window arrives. -**Offering an SLA?** More notice forgives more of a window, and longer windows are forgiven less. The 24-hour default start is not a forgiveness threshold, and notice is not guaranteed to forgive the downtime fully. A window does not block new rentals. A rental that starts after you schedule may not get forgiveness for that window. Schedule as far ahead as you can and keep the duration as short as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). +**Offering an SLA?** More notice forgives more of a window, and longer windows are forgiven less. The 24-hour default start is not a forgiveness threshold, and notice is not guaranteed to forgive the downtime fully. A window does not block new rentals. Forgiveness is per machine. It depends on how far ahead you scheduled the window and how long the window is, not on when a rental started. Schedule as far ahead as you can and keep the duration as short as you can. See [Scheduled maintenance](/host/sla-offers#scheduled-maintenance). diff --git a/host/sla-offers.mdx b/host/sla-offers.mdx index 609b5d1f..bb5a077f 100644 --- a/host/sla-offers.mdx +++ b/host/sla-offers.mdx @@ -52,8 +52,7 @@ Read [SLA in plain language](#sla-in-plain-language) before this list. Check SLA - **What Save also does:** On a machine that is already listed, **Save** publishes immediately and extends every shorter rental to the listing end date. See [SLA on extended contracts](#sla-on-extended-contracts). - **Turning SLA off later:** see [Updating SLA on an already-listed machine](#updating-sla-on-an-already-listed-machine). Unlisting and relisting can extend shorter SLA contracts. - Search hides your offer from renters whose target is above your commitment. The dashboard reliability score is not your SLA measurement. Prefer a [backtester](/host/sla-backtester) run before you enable SLA when you have history. -**API users:** `sla_not_approved`, daily `per_machine[].sla_earn`, and `sla_r_claim` as a fraction (`0.99`, not `99`) are under [API (for automation)](#api-for-automation). - + - **API users:** `sla_not_approved`, daily `per_machine[].sla_earn`, and `sla_r_claim` as a fraction (`0.99`, not `99`) are under [API (for automation)](#api-for-automation). 8. **Verify now.** In **Host → Machines**, confirm the machine shows **Listed**, then reopen **Set Pricing → SLA** and confirm your terms are saved. - **CLI:** search from a separate client account ([Testing your own machine](/host/hosting-overview#testing-your-own-machine)): `vastai search offers 'machine_id=12345 verified=any has_sla=true' --storage 10 --raw --api-key "$CLIENT_API_KEY"`. Confirm `expected_reliability` with `jq`. Do not add `expected_reliability>=…` to that query. The CLI cannot send `target_reliability`, so its `dph_total` does **not** include the SLA fee and it never shows an **SLA Fee** line. An empty result can also mean every GPU is rented or the listing is hidden. - **SLA fee:** check it in the console from that same client account (**Search → Reliability target**), then confirm the **SLA Fee** line on your offer. A REST search that sends `target_reliability` also returns the fee-inclusive `dph_total`. If the console shows no **SLA Fee** line at a target at or below your commitment, contact support. Optionally rent that offer briefly, then **Destroy** the test instance. @@ -809,7 +808,7 @@ Notify renters in the console ([Set a maintenance window](/host/set-maintenance- **Or use CLI/REST below.** Forgiveness is not guaranteed either way. -**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Notice rules are in the note above. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. A rental that starts after you schedule the window may not get that notice. Budget as if its downtime is not forgiven. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. +**Planned SLA maintenance (may reduce the service credits you owe — not guaranteed).** Schedule as far ahead as you can with [`vastai schedule maint`](/host/cli/schedule-maint) (or the [REST schedule-maintenance API](/api-reference/machines/schedule-maint)). Notice rules are in the note above. Include `--sdate`, `--duration`, and `--maintenance_category`. The CLI always sends a category; its default `"not provided"` is rejected with `invalid_args`. Use one of `power`, `internet`, `disk`, `gpu`, `software`, or `other`. Scheduling maintenance ahead can cause part of the window to count as uptime when the SLA is settled. That reduces the service credits you may owe. It does not pay you or the renter. The longer the window, the smaller the share that is forgiven. Rescheduling resets the notice clock. A rental that starts after you schedule the window may not get that notice. Forgiveness itself is per machine: it depends on how far ahead you scheduled the window and how long the window is, not on when the rental started. Budget conservatively for a short-notice window. Renters see maintenance status under **Instances**. Maintenance status is not a separate field on instance webhooks or `GET /api/v0/charges/`. The server does not currently apply `maintenance_reason`, so renters will not see a reason you send. **`sdate` is Unix epoch seconds (UTC)** for both CLI `--sdate` and the REST body. **`--duration` is in hours.** The CLI asks `Continue? [y/n]` before it sends the request; in scripts or cron, pipe the answer (`echo y | vastai schedule maint …`) or call REST directly. Schedule maintenance **sequentially** across a fleet, at least 3 seconds apart (`sleep 3` between machines; the Schedule Maintenance OpenAPI `x-rate-limit` threshold is `2.5`). If you still get HTTP 429, wait longer and retry. See [Rate Limits and Errors](/api-reference/rate-limits-and-errors). @@ -874,7 +873,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep **Console** 1. Notify renters if you can ([Set a maintenance window](/host/set-maintenance-window)). Change **Maintenance start** to a few minutes from now. The form starts 24 hours ahead. An emergency window is still unplanned, so expect full SLA exposure for it. 2. Write down every field on **Set Pricing**: GPU price, minimum GPUs, storage price, bandwidth, reserved discount, min bid, whether the listing is **hidden**, the offer end date or auto-renew duration, **Reliability Commitment**, and **Confidence**. If you unlist, you must re-enter every one of them when you relist. A blank bandwidth price publishes at $0. - 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. If a rental is still on the machine, the self-test refuses with `currently_rented` until that rental ends. Listing does not check the self-test for you. Do not turn SLA back on until it passes. The relist **Save** can extend the rental. If the machine cannot take new rentals, staying listed keeps your SLA terms. + 3. Unlist only if the machine is online and you need to stop new rentals. If it is offline, leave it listed until it reconnects. Unlisting removes the SLA terms. The self-test refuses with `currently_rented` only when it finds no rentable offer and at least one offer is already rented. A sliced machine with a rentable offer can still be tested. Listing does not check the self-test for you. Do not turn SLA back on until it passes. The relist **Save** can extend the rental. A relist without SLA can be rented before you test, and that can remove the last rentable offer. If the machine cannot take new rentals, staying listed keeps your SLA terms. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. 5. After the next UTC midnight, check **Host → Billing**. There is no separate SLA line on the normal host view, and the page shows fleet totals. Compare with a normal week. One low day can be release timing. For one machine, use `vastai show earnings`. 6. **Return to service** only if you unlisted in step 3. @@ -885,7 +884,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep c. **Run the self-test** (`vastai self-test machine MACHINE_ID`; see [Self-test](/host/upgrade-docker-and-packages#self-test)). - **If the last line is `Test completed successfully.`**, go to step d. - - **If it refuses to start** (`currently_rented`, `zero_active_offers`, or offer reliability at or below 0.90), stay listed without SLA. `currently_rented` stays until that rental ends. A **Save** that just extended it can push the end date out by days or weeks, and a machine listed without SLA can be rented again before you test. Do not pass `--ignore-requirements`. It does not get past `currently_rented`, `zero_active_offers`, or `offline_or_not_listed`. It only skips later requirement checks, such as the reliability threshold. If you need SLA on before the test can run, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID. + - **If it refuses to start** (`currently_rented`, `zero_active_offers`, or offer reliability at or below 0.90), stay listed without SLA. `currently_rented` means no rentable offer was found and at least one offer is already rented. A sliced machine with a rentable offer can still be tested. If every offer is rented, the refusal lasts until a rentable offer exists again. A **Save** that just extended it can push the end date out by days or weeks, and a machine listed without SLA can be rented again before you test. Do not pass `--ignore-requirements`. It does not get past `currently_rented`, `zero_active_offers`, or `offline_or_not_listed`. It only skips later requirement checks, such as the reliability threshold. If you need SLA on before the test can run, contact [Discord](https://discord.gg/hSuEbSQ4X8) or contact@vast.ai with the machine ID. - **If it runs and fails a check**, unlist, fix the machine using [How to self-test](/host/how-to-self-test), and repeat from step a. d. **Re-enable SLA.** Re-enter the SLA terms and click **Save**. This second **Save** sends the end date or auto-renew duration again, so it can extend shorter rentals a second time. Check the date in step a before you click it. @@ -910,7 +909,7 @@ SLA approval, settlement questions, credit disputes, and locked machines are sep ``` `show machines` leaves out machines that have been offline for more than about 10 hours. If the snapshot is empty, call `GET /api/v0/machines/?include_offline=true` with the same key (machines offline up to about 3 days). If that `include_offline` response is also empty, use the console notes above. Do not unlist until you have the terms. - 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. If a rental is still on the machine, the self-test refuses with `currently_rented` until that rental ends. Listing does not check the self-test for you. Do not turn SLA back on until it passes. Staying listed keeps the current SLA terms. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. + 3. **Unlist** only if the machine is online and you must stop new rentals. An offline machine cannot take new rentals, and unlisting drops the SLA ask. The self-test refuses with `currently_rented` only when it finds no rentable offer and at least one offer is already rented. Listing does not check the self-test for you. Do not turn SLA back on until it passes. Staying listed keeps the current SLA terms. Do not change SLA settings or relist during the outage. API users: `create_asks` returns HTTP 402 while the machine is offline. `vastai unlist machine MACHINE_ID` removes the listing and does not republish it. 4. Fix the machine. See [Machine offline](/host/machine-offline) for common causes. Existing SLA contracts keep their terms and settle against each renter's target; unlisting or setting the commitment to `0` does not change that. 5. **Check settlement** a few hours after the next UTC midnight. In the console, compare those days with a normal week in **Host → Billing**. Releases are spread over time, so one low day is not by itself a credit. To automate, read `per_machine[].sla_earn`. A backtester re-run is an estimate for one simulated contract, not the settlement record. 6. **Return to service.** diff --git a/host/upgrade-docker-and-packages.mdx b/host/upgrade-docker-and-packages.mdx index 82535abd..94ca0b13 100644 --- a/host/upgrade-docker-and-packages.mdx +++ b/host/upgrade-docker-and-packages.mdx @@ -563,7 +563,7 @@ Test completed successfully. The last line must be `Test completed successfully.` -- **If it refuses to start** (offer reliability at or below 0.90, `currently_rented`, or `zero_active_offers`): stay listed without SLA. `currently_rented` clears when that rental ends, which can be a long time if the contract was just extended. Do not pass `--ignore-requirements` to turn SLA back on. It does not clear `currently_rented` or `zero_active_offers`. It only skips later requirement checks, such as the reliability threshold. +- **If it refuses to start** (offer reliability at or below 0.90, `currently_rented`, or `zero_active_offers`): stay listed without SLA. `currently_rented` means no rentable offer was found and at least one offer is already rented. A sliced machine with a rentable offer can still be tested. Do not pass `--ignore-requirements` to turn SLA back on. It does not clear `currently_rented` or `zero_active_offers`. It only skips later requirement checks, such as the reliability threshold. - **It runs and fails a check:** the output names the check. See [How to self-test](/host/how-to-self-test). If you already relisted an SLA machine, unlist it. diff --git a/snippets/host/cli/self-test-machine.mdx b/snippets/host/cli/self-test-machine.mdx index 083ef1c3..43c6cdae 100644 --- a/snippets/host/cli/self-test-machine.mdx +++ b/snippets/host/cli/self-test-machine.mdx @@ -26,7 +26,7 @@ vastai self-test machine [--debugging] [--explain] [--api-key API_K ## Description -This command rents a test instance on a live offer, runs the tests, then destroys that instance. The machine must be listed. It refuses with `currently_rented`, `zero_active_offers`, or `offline_or_not_listed`. A scoped API key needs `machine_read`, `instance_read`, `instance_write`, and `misc` on that one key. +This command rents a test instance on a live offer, runs the tests, then destroys that instance. The machine must be listed. It refuses with `currently_rented` only when it finds no rentable offer and at least one offer is already rented. A sliced machine with a rentable offer can still be tested. It also refuses with `zero_active_offers` or `offline_or_not_listed`. A scoped API key needs `machine_read`, `instance_read`, `instance_write`, and `misc` on that one key. ## Examples