Deploy on Akash programmatically using the Console API with a managed wallet.
Note: The Console API is actively developed. See the changelog (https://github.com/akash-network/console/releases) for upcoming breaking changes.
Getting Started
Create an API Key
- Visit console.akash.network
- Sign in with your account
- Navigate to Settings → API Keys
- Click “Create API Key”
- Copy and save your API key securely
Warning: API keys grant full access to your Console account. Keep them secret.
Authentication
All requests must include the x-api-key header. Pass your API key directly in this header.
cURL example:
curl https://console-api.akash.network/v1/deployments \ -H "x-api-key: YOUR_API_KEY"If the key is missing or invalid, the API returns 401 Unauthorized:
{ "error": "Unauthorized", "message": "Invalid API key" }Security practices:
- Store the key in an environment variable (
AKASH_API_KEY), never in source code. - Rotate keys in Console under Settings → API Keys to keep your workflows safe in case of key compromise.
- Keys grant full access to your Console account, so treat them like passwords.
Response envelope
Every JSON response from the Console API is wrapped in a top-level data field, for example:
{ "data": { "dseq": "1234567", "manifest": "...", "signTx": { ... } } }All examples in this guide show the full response body — extract the value you need from response.data.
Money fields
The Managed Wallet bills your Console account in USD (credit card). You add credits to the account, and Console funds your deployments from that balance on its own. Creating a deployment takes no deposit, and keeping one running takes no top-up call. See How Funding Works for the full model, or read the current platform figures from GET /v1/deployment-funding-config.
The blockchain itself works in raw on-chain denoms (uact, uusdc, …). Wherever you see price.denom / price.amount in a bid response or an escrow_account.state.funds entry, those are raw chain values in micro-units (1 ACT = 1 000 000 uact). The SDL pricing block also uses chain denoms — the managed wallet handles the USD ↔ chain conversion for you.
Complete Deployment Workflow
1. Create Deployment
POST your SDL to create a deployment. Console funds it automatically from your account balance, so the request carries no deposit. The API returns a dseq (deployment sequence number) that identifies the deployment in all subsequent calls. The response also returns the broadcast transaction hash for the on-chain MsgCreateDeployment.
cURL:
curl -X POST https://console-api.akash.network/v1/deployments \ -H "x-api-key: $AKASH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "data": { "sdl": "<YOUR_SDL_YAML_AS_STRING>" } }'JavaScript (fetch):
const res = await fetch("https://console-api.akash.network/v1/deployments", { method: "POST", headers: { "x-api-key": process.env.AKASH_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ data: { sdl: YOUR_SDL_STRING } }),});const { data } = await res.json();const dseq = data.dseq;Response (201 Created):
{ "data": { "dseq": "1234567", "manifest": "<computed manifest hash + manifest blob>", "signTx": { "code": 0, "transactionHash": "ABCDEF...", "rawLog": "[...]" } }}2. Wait for and Fetch Bids
List bids for your deployment. Bids typically arrive within 30–60 seconds. The response is wrapped in data and each bid is identified by a composite id (owner/dseq/gseq/oseq/provider/bseq), not a single opaque string.
cURL:
curl "https://console-api.akash.network/v1/bids?dseq=1234567" \ -H "x-api-key: $AKASH_API_KEY"JavaScript (fetch):
const res = await fetch( `https://console-api.akash.network/v1/bids?dseq=${dseq}`, { headers: { "x-api-key": process.env.AKASH_API_KEY } },);const { data: bids } = await res.json();Response:
{ "data": [ { "bid": { "id": { "owner": "akash1ownerxxx...", "dseq": "1234567", "gseq": 1, "oseq": 1, "provider": "akash1providerxxx...", "bseq": 92 }, "state": "open", "price": { "denom": "uact", "amount": "10000" }, "created_at": "92", "resources_offer": [ { "resources": { "cpu": { "units": { "val": "500" } }, "memory": { "quantity": { "val": "536870912" } }, "storage": [], "endpoints": [] }, "count": 1 } ] }, "escrow_account": { "id": { "scope": "bid", "xid": "..." }, "state": { "owner": "akash1providerxxx...", "state": "open", "transferred": [], "settled_at": "...", "funds": [], "deposits": [] } } } ]}Polling example:
async function waitForBids(dseq, { pollMs = 3000, maxAttempts = 20 } = {}) { for (let i = 0; i < maxAttempts; i++) { const res = await fetch( `https://console-api.akash.network/v1/bids?dseq=${dseq}`, { headers: { "x-api-key": process.env.AKASH_API_KEY } }, ); const { data } = await res.json(); if (data.length > 0) return data; await new Promise((r) => setTimeout(r, pollMs)); } throw new Error("No bids received within timeout");}3. Create Lease
Accept one or more bids to activate the deployment lease(s) and send the manifest to the chosen provider(s) in a single call.
Pick the bid(s) you want, then build the leases[] array from the bid id (omitting owner and bseq). The manifest field is the rendered manifest produced by the SDL — you can re-use the manifest hash returned by POST /v1/deployments if you cached it.
cURL:
curl -X POST https://console-api.akash.network/v1/leases \ -H "x-api-key: $AKASH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "manifest": "<MANIFEST_FROM_CREATE_DEPLOYMENT>", "leases": [ { "dseq": "1234567", "gseq": 1, "oseq": 1, "provider": "akash1providerxxx..." } ] }'JavaScript (fetch):
const chosen = bids[0].bid.id;const res = await fetch("https://console-api.akash.network/v1/leases", { method: "POST", headers: { "x-api-key": process.env.AKASH_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ manifest, leases: [ { dseq: chosen.dseq, gseq: chosen.gseq, oseq: chosen.oseq, provider: chosen.provider, }, ], }),});const { data } = await res.json();Response (200 OK) is the same shape as GET /v1/deployments/{dseq} — the full deployment object including its now-active lease(s):
{ "data": { "deployment": { "id": { "owner": "akash1ownerxxx...", "dseq": "1234567" }, "state": "active", "hash": "...", "created_at": "92" }, "leases": [ { "id": { "owner": "akash1ownerxxx...", "dseq": "1234567", "gseq": 1, "oseq": 1, "provider": "akash1providerxxx...", "bseq": 92 }, "state": "active", "price": { "denom": "uact", "amount": "10000" }, "created_at": "92", "closed_on": "", "status": null } ], "escrow_account": { "id": { "scope": "deployment", "xid": "..." }, "state": { "owner": "akash1ownerxxx...", "state": "open", "transferred": [], "settled_at": "...", "funds": [{ "denom": "uact", "amount": "5500000" }], "deposits": [] } } }}4. Add Deposit to Deployment (Deprecated)
Deprecated: Console tops your deployments up automatically for as long as your account has credits, so there is nothing for this endpoint to do. It still accepts requests for existing integrations and will be removed in a future release. Add credits to your account instead. See How Funding Works.
cURL:
curl -X POST https://console-api.akash.network/v1/deposit-deployment \ -H "x-api-key: $AKASH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "data": { "dseq": "1234567", "deposit": 0.5 } }'JavaScript (fetch):
const res = await fetch( "https://console-api.akash.network/v1/deposit-deployment", { method: "POST", headers: { "x-api-key": process.env.AKASH_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ data: { dseq, deposit: 0.5 } }), },);const { data } = await res.json();Response (200 OK): the full deployment object after the top-up.
{ "data": { "deployment": { "...": "..." }, "leases": [], "escrow_account": { "...": "..." } }}5. Close Deployment
Close a deployment. Whatever it has not yet spent returns to your Console account balance.
cURL:
curl -X DELETE "https://console-api.akash.network/v1/deployments/1234567" \ -H "x-api-key: $AKASH_API_KEY"JavaScript (fetch):
const res = await fetch( `https://console-api.akash.network/v1/deployments/${dseq}`, { method: "DELETE", headers: { "x-api-key": process.env.AKASH_API_KEY }, },);const { data } = await res.json();Response (200 OK):
{ "data": { "success": true } }Settlement happens on-chain, so the credited amount takes a short while to appear. Call GET /v1/deployments/{dseq} afterward to inspect the final state, or check your balance in the Console UI.
Complete Example Script
This example runs the full managed-wallet deployment flow in one script.
const API_BASE_URL = "https://console-api.akash.network";const API_KEY = process.env.AKASH_API_KEY;
if (!API_KEY) { throw new Error("Set AKASH_API_KEY before running this script.");}
const SDL = `version: "2.0"services: web: image: nginx:stable expose: - port: 80 as: 80 to: - global: trueprofiles: compute: web: resources: cpu: units: 0.5 memory: size: 512Mi storage: - size: 512Mi placement: dcloud: pricing: web: denom: uact amount: 10000deployment: web: dcloud: profile: web count: 1`;
async function apiRequest(path, options = {}) { const res = await fetch(`${API_BASE_URL}${path}`, { ...options, headers: { "x-api-key": API_KEY, "Content-Type": "application/json", ...(options.headers || {}), }, });
if (!res.ok) { const body = await res.text(); throw new Error(`HTTP ${res.status}: ${body}`); } return res.json();}
async function waitForBids(dseq, { pollMs = 3000, maxAttempts = 20 } = {}) { for (let i = 0; i < maxAttempts; i++) { const { data } = await apiRequest(`/v1/bids?dseq=${dseq}`); if (data.length > 0) return data; await new Promise((resolve) => setTimeout(resolve, pollMs)); } throw new Error("No bids received within timeout");}
async function main() { const create = await apiRequest("/v1/deployments", { method: "POST", body: JSON.stringify({ data: { sdl: SDL } }), }); const { dseq, manifest } = create.data;
const bids = await waitForBids(dseq); const chosenId = bids[0].bid.id;
await apiRequest("/v1/leases", { method: "POST", body: JSON.stringify({ manifest, leases: [ { dseq: chosenId.dseq, gseq: chosenId.gseq, oseq: chosenId.oseq, provider: chosenId.provider, }, ], }), });
const status = await apiRequest(`/v1/deployments/${dseq}`); console.log("Deployment status:", status);
const closed = await apiRequest(`/v1/deployments/${dseq}`, { method: "DELETE", }); console.log("Closed deployment:", closed);}
main().catch((err) => { console.error(err); process.exit(1);});Confidential Compute (TEE)
Run your workload inside a hardware-isolated Trusted Execution Environment (TEE) by adding a single params.tee field to a service in your SDL. Set it to cpu for a CPU-only confidential VM, or cpu-gpu to combine confidential compute with GPU acceleration. The provider selects the underlying hardware platform (AMD SEV-SNP or Intel TDX) and handles attestation automatically — you only choose the TEE option, nothing else.
Confidential Compute is requested entirely through the SDL, so there are no extra API parameters: pass the SDL below as data.sdl on POST /v1/deployments exactly as in Step 1.
CPU-only Confidential Compute
version: "2.1"services: web: image: nginx:stable expose: - port: 80 as: 80 to: - global: true params: tee: cpuprofiles: compute: web: resources: cpu: units: 0.5 memory: size: 512Mi storage: - size: 512Mi placement: dcloud: pricing: web: denom: uact amount: 10000deployment: web: dcloud: profile: web count: 1GPU + Confidential Compute
The cpu-gpu option requires GPU resources in the compute profile — a cpu-gpu deployment without a gpu block is rejected.
version: "2.1"services: inference: image: my-model:latest expose: - port: 8080 as: 8080 to: - global: true params: tee: cpu-gpuprofiles: compute: inference: resources: cpu: units: 8 memory: size: 32Gi storage: - size: 100Gi gpu: units: 1 attributes: vendor: nvidia: - model: h100 placement: dcloud: pricing: inference: denom: uact amount: 100000deployment: inference: dcloud: profile: inference count: 1Warning: TEE services can only pull images from public registries. The
credentialsfield is not honored for confidential workloads, and a deployment that references a private image will fail. Make sure everyimagein a TEE service is publicly pullable.
TEE type reference
| Value | Description |
|---|---|
cpu | CPU-only confidential VM |
cpu-gpu | Confidential VM with NVIDIA GPU CC (requires GPU resources) |
The provider selects the actual hardware platform (AMD SEV-SNP or Intel TDX) and the runtime automatically at deployment time — you do not choose or configure it.
All services within the same deployment group must use the same TEE type (or none at all); mixing TEE types in a single group is rejected.
For attestation, the security model, and supported hardware, see the Confidential Compute (TEE) core concepts and the SDL advanced features reference.
Best Practices
Security
- Never commit API keys to version control
- Use environment variables for API keys
- Rotate keys regularly as a security best practice
- Restrict key permissions if possible
// Good: use environment variablesconst API_KEY = process.env.AKASH_API_KEY;
// Bad: hardcoded keyconst API_KEY = "ac.sk.mainnet.xxx...";Error Handling
Use HTTP status codes to determine recovery behavior.
| Status | Meaning | Common cause |
|---|---|---|
| 200 OK | Request succeeded | - |
| 201 Created | Resource created | POST /v1/deployments, POST /v2/deployment-settings |
| 400 Bad Request | Invalid input | Malformed SDL, missing required field |
| 401 Unauthorized | Auth failed | Missing or invalid x-api-key |
| 404 Not Found | Resource not found | dseq does not exist or belongs to another user |
| 429 Rate Limited | Rate limited | Polling interval too fast or burst of requests |
| 500 Internal Server Error | Server error | Retry with exponential backoff |
Error response shape:
{ "error": "BadRequest", "message": "SDL validation failed: missing 'profiles' section"}Polling for Bids
Poll every 3 seconds for 30–60 seconds, then back off or return a timeout error.
Managed Wallet vs SDK
| Feature | Managed Wallet API | Akash SDK |
|---|---|---|
| Wallet Management | Managed by Console | You manage wallet |
| Authentication | API Key | Private key/mnemonic |
| Payment | Credit card (USD) | Crypto (AKT) |
| API Type | REST API | Native blockchain |
| Language | Any (HTTP) | Go, TypeScript |
| Setup | API key only | Wallet + blockchain setup |
| Best For | SaaS, web apps | Blockchain apps, CLI tools |
Limitations
- Payment method: Credit card only. Existing wallets cannot be linked to a Managed Wallet account at this time.
- Wallet access: Console manages the wallet. You cannot export private keys or sign arbitrary transactions.
- API stability: Pin integrations to
v1orv2. Versions are independent, and breaking changes are announced in the changelog (https://github.com/akash-network/console/releases). - For production workloads without managed wallet constraints: use the Akash SDK or CLI with your own wallet.
Resources
- API Reference - Complete endpoint documentation
- Quickstart - End-to-end deployment in five API calls
- SDL Reference - SDL syntax guide
- Console Documentation - Console overview
- Confidential Compute (TEE) - Attestation and security model
Need Help?
- Discord: discord.akash.network
- GitHub Issues: console/issues
- Support: GitHub Support