SwarmDoGPU API
A REST/JSON API for renting GPUs across providers behind one masked catalog. Everything the dashboard, CLI, SDK and MCP server do is this API. Base URL:
Machine-readable: /openapi.json (OpenAPI 3.1, the customer surface with one operation per route) · agents: hosted MCP.
All request/response bodies are JSON. The backing provider (Vast, RunPod, partner hosts…) is never exposed to customers — offers, endpoints and instances are masked.
Quickstart · first call in five minutes
Create an account at /app, add credit (minimum $5) and copy an API key from Keys. Every call below uses that key as a bearer token; the charge for a call comes back in the x-swarmdo-charged-cents header.
1. Generate a video with a hosted model
curl -X POST https://gpu.swarmdo.com/api/managed/kling-2-1-pro/runsync \
-H "Authorization: Bearer $SWARMDO_API_KEY" -H "content-type: application/json" \
-d '{"input":{"image":"https://example.com/frame.png","prompt":"slow dolly in","duration":5}}'
GET /api/managed/models lists every model with its price and the durations or tiers it sells; a job that outlives the call returns an id to poll at GET /api/managed/{id}/status/{jobId}.
2. Serve a language model behind an OpenAI-compatible URL
curl -X POST https://gpu.swarmdo.com/api/models/<catalog-model-id>/deploy -H "Authorization: Bearer $SWARMDO_API_KEY" # then, with any OpenAI client: base_url = "https://gpu.swarmdo.com/run/<endpoint-id>/openai/v1"
Endpoints scale to zero and bill per GPU-second while a request runs. The dashboard's Models tab does the deploy in one click and shows the invoke URL.
3. Give an agent the keys
claude mcp add swarmdo-gpu --env SWARMDO_API_KEY=swdo_… -- npx -y @swarmdo/gpu-mcp # 44 tools npm i @swarmdo/gpu-sdk # TypeScript SDK; see "Client libraries" below
Authentication
Most endpoints require an authenticated account. Two credentials work interchangeably on data endpoints:
State-changing requests made with a session cookie are CSRF-checked (Origin must match Host); Bearer-key requests are exempt. Create/manage keys under Dashboard → Keys.
Errors & rate limits
Every response carries x-swarmdo-request-id; quote it to support. Every error body is { "error": message, "code": stable_code, "requestId", "details"?: [{field, message}] }. Codes: invalid_request (400, details lists every failing field), unauthorized (401), insufficient_credit (402, nothing was spent), not_found (404), spend_cap and unpriceable (409), rate_limited (429, with retryAfterMs), upstream_error / upstream_rate_limited / upstream_ambiguous (502), internal_error (500). Rate-limited routes return RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset (seconds) and RateLimit-Policy on every response, and Retry-After on a 429, so a client can pace itself. Limits are per client address and per action: sign-in and sign-up 10/min, top-ups 10/min, hosted MCP 600/min, Assay metering 1,200/min.
Errors return the matching HTTP status with a JSON body { "error": "message" }. Common: 400 validation, 401 not signed in, 402 insufficient credit, 404 not found, 409 spend-cap/margin, 429 rate-limited, 502 upstream provider error. Auth, provisioning and payment routes are rate-limited per IP/action.
Catalog · 🌐 public
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/offers | 🌐 | Masked GPU catalog. Query: gpuClass, region, maxUsdPerHr, minGpuRamGb, interruptible, sort. Returns offers + facets. |
| GET | /api/models | 🌐 | One-click deployable model catalog. |
| GET | /api/serverless/offers | 🌐 | Serverless GPU endpoint pricing. |
| GET | /api/storage/offers | 🌐 | Persistent-volume tiers & prices. |
| GET | /api/sla/tiers | 🌐 | Reliability tiers + uptime-credit terms. |
| GET | /api/reservations/plans | 🌐 | Committed-use savings plans. |
| GET | /api/trust | 🌐 | Anonymized fleet hardware-attestation trust. |
| GET | /api/health | 🌐 | Liveness probe. |
Accounts & auth · 🌐/🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/auth/config | 🌐 | Which sign-in methods are enabled. |
| POST | /api/auth/register | 🌐 | Create an account. Body { email, password }. |
| POST | /api/auth/login | 🌐 | Sign in. Body { email, password, code? } (2FA code if enabled). |
| GET | /api/auth/google | 🌐 | Start Google SSO (redirect). |
| POST | /api/auth/logout | 🔑 | End the current session. |
| GET | /api/auth/me | 🔑 | The authenticated account. |
| POST | /api/auth/change-password | 🔑 | Rotate password. |
| POST | /api/auth/2fa/setup · /enable · /disable | 🔑 | TOTP two-factor lifecycle. |
| POST | /api/auth/request-password-reset · /reset-password · /verify-email | 🌐 | Email-based recovery & verification. |
Rentals
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/rentals | 🔑 | Rent a GPU. Body { sku, maxSpendCents?, image?, sshPublicKey?, failover? }. |
| GET | /api/rentals | 🔑 | Your rentals. |
| GET | /api/rentals/{id} | 🔑 | Live status + masked endpoints. |
| POST | /api/rentals/{id}/terminate | 🔑 | Stop the instance. |
| GET | /api/rentals/{id}/invoice | 🔑 | Final invoice. |
| POST | /api/rentals/{id}/checkpoints · /migrate | 🔑 | Snapshot a workload / migrate it to a fresh instance. |
| POST | /api/rentals/{id}/rating | 🔑 | Rate a finished rental. |
Telemetry & alerts · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/rentals/{id}/telemetry | 🔑 | Time-series GPU metrics (query window, points). |
| GET | /api/rentals/{id}/telemetry/latest | 🔑 | Latest sample. |
| POST | /api/rentals/{id}/telemetry | 🔑 | Ingest a live sample (in-instance agent). |
| POST | /api/rentals/{id}/telemetry/simulate | 🔑 | Backfill a demo series. |
| GET POST | /api/alerts | 🔑 | List / create threshold alert rules. |
| PATCH DEL | /api/alerts/{id} | 🔑 | Update / delete a rule. |
Idle detection & auto-stop · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/idle | 🔑 | Policy + per-instance idle assessment. |
| PUT | /api/idle/policy | 🔑 | Set threshold / minutes / action (notify·stop·hibernate). |
| POST | /api/idle/sweep | 🔑 | Enforce the policy on idle instances now. |
Billing · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/billing/summary | 🔑 | Balance, burn rate, runway. |
| GET | /api/billing/config | 🌐 | Whether card top-ups are enabled + limits. |
| GET | /api/billing/transactions · /daily | 🔑 | Ledger history & daily charges. |
| GET PUT | /api/billing/budget | 🔑 | Monthly budget + forecast. |
| GET PUT | /api/billing/auto-topup | 🔑 | Automatic top-up. GET returns the rule, the card on file (brand + last four) and blocked when it cannot run. PUT saves { enabled, thresholdCents, amountCents }: when the balance drops below the threshold, the amount is charged to the card on file and credited. Bounded by a 15-minute cooldown, six charges a day, and three consecutive failures (then the rule switches itself off and you are notified). |
| POST | /api/billing/topup | 🔑 | Pass saveCard: true to keep the card for automatic top-ups. Start a Stripe Checkout top-up; returns the hosted URL. |
| POST | /api/billing/webhook | 🌐* | Stripe webhook (signature-verified). Credits the ledger. |
SLA · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET PUT | /api/sla | 🔑 | Status (uptime vs target) / choose a tier. |
| POST | /api/sla/settle | 🔑 | Settle the period — auto-credit on breach. |
| POST | /api/sla/simulate-outage | 🔑 | Record a demo outage. |
Reserved capacity · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET POST | /api/reservations | 🔑 | List / reserve committed capacity under a savings plan. |
| POST | /api/reservations/{id}/cancel | 🔑 | Cancel a reservation. |
Storage & datasets · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET POST | /api/storage/volumes | 🔑 | List / create persistent volumes. |
| GET DEL | /api/storage/volumes/{id} | 🔑 | Get / delete a volume. |
| GET POST | /api/datasets | 🔑 | List / create portable datasets. |
| POST | /api/datasets/{id}/attach · /detach | 🔑 | Mount/unmount a dataset on a rental. |
Serverless & models · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET POST | /api/serverless/endpoints | 🔑 | List / deploy autoscaling GPU endpoints. Deploy body { name, gpuClass: RTX4090|L40S|A100|H100, image, region: us-east|us-west|eu-west, minWorkers (0 = scale-to-zero), maxWorkers }. Optional: env (container vars), diskGb, keepWarm (a worker stays ready 24/7, billed per reserved GPU-second on top of usage), prebakedModelId (fast cold start), startCmd — your image's own start command, which also turns on container log forwarding (see below). |
| GET DEL | /api/serverless/endpoints/{id} | 🔑 | Get / delete (remove). Lifecycle: POST /scale { minWorkers, maxWorkers }, POST /suspend (pause + release hold), POST /resume (restart). GET /status — live diagnostics: masked job/worker counts plus a derived state (serving / starting / stuck / throttled / failing / idle) so you can see why an endpoint isn't responding. |
| POST | /api/models/{id}/deploy · /prewarm | 🔑 | One-click deploy or prewarm a catalog model. |
| GET | /api/managed/models | — | Managed models — fully hosted, nothing to rent or deploy. Returns each model's id, modality, billing unit and usdPerUnit (language models also return usdPerUnitInput, per million tokens). Video models list clipSeconds, the only duration values accepted — anything else is refused with a 400 rather than billed at a guess, and an unstated duration is pinned to the model's default. Models priced by a request field return pricingTiers (e.g. size: 480p / 720p); that field is required. |
| POST | /api/managed/{id}/{path} | 🔑 | Call a managed model. {path} is the model's own sub-path — openai/v1/chat/completions for an OpenAI-compatible language model, run or runsync for the job API. The response is passed through verbatim; the charge for the call is returned in x-swarmdo-charged-cents. |
| GET | /api/managed/{id}/schema | — | JSON Schema (2020-12) for the request — the clip lengths and tiers the call enforces, typed — and outputRetention, how long the output URL in a reply stays downloadable (7 days for the video models; copy the file to your own storage before then). The same fields appear on every item of GET /api/managed/models. GET /llms.txt indexes the machine-readable surfaces for agents. |
| POST | /api/managed/{id}/quote | 🔑 | What a request would cost before anything is spent: the same validation as the real call, the same quote it bills from. Returns estimatedCents (null for token models, which bill from the reply's usage). A failed or refused job is never billed and now says why: category is one of content_policy, invalid_input, capacity, timeout, upstream_error, with billed:false. |
| GET | /api/managed/{id}/status/{jobId} | 🔑 | Poll a job that outlived its call (run, or a runsync that returned IN_PROGRESS). Only the account that submitted the job can read it. The first completed read settles the bill against what the provider actually generated — x-swarmdo-charged-cents carries the difference (negative when refunded), and a failed job is refunded in full. |
Invoking an endpoint. Send inference to the masked URL returned at deploy — https://gpu.swarmdo.com/run/<id>/<path> — authenticating with your swdo_ API key as a Bearer token. The gateway routes to the backing GPU provider (chosen for lowest cost, kept hidden) and meters usage. RunPod-backed endpoints accept the job path /runsync (body { "input": { … } }) and the OpenAI-compatible base /openai/v1 (e.g. use https://gpu.swarmdo.com/run/<id>/openai/v1 as your OpenAI base URL).
Drop-in for OpenAI clients
A serverless endpoint that serves an OpenAI-compatible model answers at https://gpu.swarmdo.com/run/<id>/openai/v1. Anything that takes a base URL and an API key works unchanged — set the base URL to that, the key to your swdo_ key, and the model name to whatever the endpoint serves.
# Python (openai)
client = OpenAI(base_url="https://gpu.swarmdo.com/run/<id>/openai/v1", api_key=os.environ["SWARMDO_API_KEY"])
# Node (openai)
const client = new OpenAI({ baseURL: "https://gpu.swarmdo.com/run/<id>/openai/v1", apiKey: process.env.SWARMDO_API_KEY });
# Vercel AI SDK
const swarmdo = createOpenAI({ baseURL: "https://gpu.swarmdo.com/run/<id>/openai/v1", apiKey: process.env.SWARMDO_API_KEY });
# Cursor · Continue · Open WebUI · LibreChat · SillyTavern
# provider: OpenAI-compatible · base URL: https://gpu.swarmdo.com/run/<id>/openai/v1 · API key: swdo_…
# (Open WebUI: Settings → Connections → OpenAI API; Continue: "provider": "openai", "apiBase": …)
Streaming (stream: true) is relayed chunk by chunk. The endpoint scales to zero, so the first request after idle pays a cold start; keep-warm avoids it at a warm-time cost shown on the endpoint.
Managed models vs. serverless. Deploy a serverless endpoint when you need your own image, your own weights, or control over autoscaling — you pay per GPU-second the workers are active. Use a managed model when you just want inference: there is no endpoint, no worker, no cold start and no idle cost, and you are billed per unit of work (tokens for language models, seconds for video, per request otherwise). Billing is per successful call only — a failed call costs nothing. One practical note for reasoning models: their thinking counts as output tokens, so a small max_tokens can be consumed entirely by reasoning and return empty content — give them headroom. Both are masked identically: you never see which provider is behind either.
Debugging an endpoint. GET /api/serverless/endpoints/{id}/logs?limit=N returns recent masked lines (newest first) — every invoke the gateway handled, plus anything the container pushed. Remediation without leaving the platform: POST /{id}/purge-queue drops a wedged backlog, POST /{id}/restart bounces the workers. To get the container's own output — the stdout/stderr of your model server, which is where a failed load actually prints — pass startCmd at deploy (e.g. "python -u handler.py"): we run it wrapped so its output is streamed to your log endpoint as well as the console. It's opt-in because we won't override your image's start command uninvited, and it needs your real one. If the forwarder can't run or can't reach us, your worker is unaffected — it keeps serving and logging locally.
Custom domain (admin only). Map your own hostname to an endpoint so callers use https://api.yourco.com/… instead of the /run/<id> path. POST /api/serverless/endpoints/{id}/domains { domain } returns the DNS to publish (a CNAME to the platform host + a _swarmdo-verify TXT); POST /api/serverless/domains/{domId}/verify checks the TXT and activates it; DELETE /api/serverless/domains/{domId} removes it. Once active, requests arriving on that Host route straight to the endpoint (masked).
Builds — from GitHub · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET POST | /api/builds | 🔑 | List / start a build. Body { repoUrl (https://github.com/org/repo), ref?, dockerfilePath?, contextDir? } — builds a container image from the repo's Dockerfile. |
| GET | /api/builds/{id} | 🔑 | Get a build's status + resulting image ref. |
| POST | /api/builds/{id}/sync | 🔑 | Poll the backing builder and refresh the build's status. |
On success the build's imageRef can be deployed straight to a serverless endpoint (POST /api/serverless/endpoints with that image). The backing builder is masked behind the platform.
Jobs & cache · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET POST | /api/jobs | 🔑 | List / submit batch jobs; /api/jobs/{id}, /{id}/cancel. |
| GET POST | /api/cache | 🔑 | Fleet image/model-weight cache + prewarm. |
Squads (teams) · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET POST | /api/teams | 🔑 | List / create squads (pooled-credit cost centers). |
| GET | /api/teams/{id} (+ members, contribute, allocate) | 🔑 | Manage roster & shared credit. |
Keys · secrets · account · 🔑
| Method | Path | Auth | Description |
|---|---|---|---|
| GET POST DEL | /api/keys · /api/keys/{id} | 🔑 | List / create / revoke API keys. |
| GET DEL | /api/sessions · /api/sessions/{id} | 🔑 | Active sessions & revocation. |
| GET POST DEL | /api/secrets · /api/secrets/{key} | 🔑 | Encrypted per-account env-var vault. |
| GET POST | /api/notifications · /read | 🔑 | In-app feed + mark read. |
| GET | /api/account · /api/audit · /api/referrals | 🔑 | Profile, your activity log, affiliate referrals. |
Host / supplier API · 🏷️
Independent providers list GPUs for resale. Authenticate with a supplier key (returned once at registration).
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/suppliers/register | 🌐 | Onboard a supplier; returns the API key once. |
| GET POST | /api/suppliers/listings | 🏷️ | List / create GPU listings (+ /{id} PUT). |
| GET POST | /api/suppliers/attestations | 🏷️ | Submit hardware attestation (GPU/VRAM/benchmark) + history. |
| POST | /api/host/register, GET /api/host | 🔑 | P2P host — a logged-in user rents out their own GPU. |
Operator · ⚙️
Admin-only, under /api/admin/*. Accepts an admin-role session or the x-admin-token. The operator console (/admin) is the UI for these — including toggling upstream providers on/off, markup rules, user management, provider reputation, host attestation, and user impersonation.
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/dashboard · /audit · /users · /suppliers · /attestations | Operational views (margins, catalog, rentals, users, suppliers). |
| GET PUT | /api/admin/markup · /providers · /flags | Tune markup, toggle upstream providers, global kill-switches. |
| POST | /api/admin/impersonate · /attestations/simulate · /sla/incident | View-as-user, record attestations / SLA incidents. |
Assay — answers checked before they return · 🔑 same key, same balance
Assay is an OpenAI-compatible chat API served from its own host and billed to this platform's prepaid balance with your normal swdo_ key (Authorization: Bearer; api-key and x-api-key also accepted). Each request runs N candidate answers, checks them, and returns the model's best attempt, verified by running it, with the scores reported per call. The aliases are third-party hosted models selected by SwarmDo. Point any OpenAI SDK at https://assay.api.swarmdo.com/v1; stream: true works; GET /v1/models lists the aliases. Charges appear in the spend explorer under Assay.
curl https://assay.api.swarmdo.com/v1/chat/completions \
-H "Authorization: Bearer $SWARMDO_API_KEY" -H "content-type: application/json" -H "x-verifier-n: 4" \
-d '{"model":"assay-chart","max_tokens":2000,"messages":[{"role":"user","content":[
{"type":"text","text":"Write matplotlib code that reproduces this chart. Reply with one python code block."},
{"type":"image_url","image_url":{"url":"data:image/png;base64,..."}}]}]}'
The reply is the normal OpenAI shape with exactly one choice — the verified winner — plus a report of what selection bought on that call:
"x_verifier": {"n":4,"mode":"visual","scores":[0.0,0.71,0.84,0.66],"first_score":0.0,"selected_score":0.84,"selected_index":2,
"upstream_calls":4,"charged_cents":1,"latency_s":18.2}
selected_index is 0 when the reply is the answer you would have received without Assay; anything else means selection changed it. An identical request within 90 s replays the earlier reply (x_verifier.replayed: true); send x-assay-idempotency: off to generate afresh.
| Model | Verifies | Caps (prompt chars / max_tokens / N) | Price |
|---|---|---|---|
assay-fast | general answers | 60,000 / 4,096 / 4 | $0.01 per verified request |
assay-chart | with an image: rendered and compared to it (mode: "visual"); without: each candidate runs and draws a figure (mode: "render"). Without an image, Assay can only check that the code runs and draws, so it rescues prompts whose first attempt fails and does nothing for charts that already run (measured: +0.05 on assay-chart, +0.14 on assay-fast); for text-to-chart without an image, assay-fast is the better pick. | 32,000 / 4,096 / 4 | $0.01 per verified request |
assay-code | the edit is applied to the file you supply as "assay_files": {"path": "contents"} and parsed (mode: "code"); the field is stripped before the model sees it; running a repository's tests needs Assay beside the repo | 120,000 / 4,096 / 4 | $0.02 per verified request |
assay-pro | the strongest alias | 96,000 / 2,048 / 4 | $0.60 per verified request |
| Pass-through | a request with nothing to verify (mode: "passthrough") | — | the backend's list price × 1.5 per token, rounded up per call (a small call is 1c) |
On our held-out chart set (n=64, best-of-4 through the hosted endpoint, two runs each): assay-chart went from 0.50 to 0.67 and 0.65 (CI excludes zero; none worse), median 16–18 s, p95 28–51 s; assay-fast from 0.42 to 0.68 and 0.66 (CI excludes zero; none worse), median 32–34 s, p95 66–71 s, so for charts either alias is a fair pick at the same price; assay-pro from 0.75 to 0.78 (CI excludes zero; none worse), median 12.5 s, p95 21 s — the interactive tier; its lift is small because the strongest backend is rarely wrong on the first try. Zero of 320 task-runs across the five runs scored below its first candidate. Treat both as background calls, or use the async flow. For code, we measured the apply-and-parse check on its own and it does not move the resolve rate (+1 of 107); running the project's tests, which needs Assay beside the repo, is where the code result comes from. Async: send x-assay-async: 1 to get 202 {"id","status":"queued","poll":"/v1/jobs/<id>","expires_after_s":900}, then GET /v1/jobs/<id> with the same key returns {"status":"queued|running|done|failed","result":{…}}; results are kept 15 minutes, per key. GET /health lists the verifiers available (visual, render, code-apply). Running Assay locally (the code product's tests rung needs it beside your repo): the launcher meters against your account with your own key — POST /api/assay/meter with {"cents", "ref": "assay_…", "description"?}, idempotent on ref; it answers 402 with your balance when credit is at or below zero, and the launcher then stops verifying until you add credit.
Local launcher (the code product). GET https://assay.api.swarmdo.com/v1/launcher with your key returns assay-local.tar.gz (~53 KB: run.sh, README, proxy modules, a local catalogue). tar xzf assay-local.tar.gz && cd assay-local && SWDO_KEY=swdo_… BACKEND_KEY=<OpenRouter or any OpenAI-compatible key> ./run.sh serves an OpenAI-compatible endpoint at http://127.0.0.1:8188/v1 (needs python 3.10–3.13 or uv, and curl). It applies each candidate edit in a scratch copy of the repository named by the agent's working directory: line (confined to ASSAY_REPO_ROOT, default $HOME) and runs the project's tests (ASSAY_TEST_CMD for a fast scoped command); the candidate whose tests pass wins. Verified requests are metered to your account (assay-code 3c, other aliases 1c); pass-throughs are not charged by us. Measured in this mode only: blind single-shot django patches 32/107 → best-of-5 43/107 when tests can run (exact McNemar p=9.8e-04; the model must be shown the file).
x-verifier-n is optional (default 4, capped per alias). A prompt over its cap is refused with 413 before any model call; max_tokens above the cap is clamped and reported in x_verifier.limits. An account without credit gets 402 before any token is spent. Raw upstream model slugs are refused with 400 — use the aliases.
Client libraries — SDK · CLI · MCP
Hosted MCP — https://gpu.swarmdo.com/mcp
The same 44 tools as the npm package, served over MCP's Streamable HTTP transport with your API key as a bearer header, so an agent needs no local process. Stateless: every POST is a complete JSON-RPC exchange; a notification is acknowledged with 202; no server-initiated stream is offered (GET answers 405). Tool calls run as your key against this API, so credit, fraud and rate limits apply exactly as they do to you.
# Claude Code
claude mcp add --transport http swarmdo-gpu https://gpu.swarmdo.com/mcp --header "Authorization: Bearer swdo_…"
# Cursor / any client with a JSON config
{ "mcpServers": { "swarmdo-gpu": { "url": "https://gpu.swarmdo.com/mcp", "headers": { "Authorization": "Bearer swdo_…" } } } }
# by hand
curl -X POST https://gpu.swarmdo.com/mcp -H "Authorization: Bearer $SWARMDO_API_KEY" -H "content-type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Status: the TypeScript SDK (@swarmdo/gpu-sdk) and the MCP server (@swarmdo/gpu-mcp) are both published on npm. The @swarmdogpu/cli lives in the repo and isn't published yet — run it from the monorepo, or use the REST API directly (every example above).
TypeScript SDK
CLI
MCP server (Claude Code / Desktop)
44 tools: catalog search and rentals, serverless deploy/scale/suspend/invoke, and the full diagnostic set — serverless_status, serverless_logs, serverless_purge_queue, serverless_restart — so an agent can resolve a stuck endpoint without you opening a provider console.
SwarmDoGPU API reference · base https://gpu.swarmdo.com · manage keys in the dashboard.