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": "Missing or 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.
Complete Deployment Workflow
1. Create Deployment
POST your SDL to create a deployment. The API returns a dseq (deployment sequence number) that identifies the deployment in all subsequent calls.
cURL:
curl -X POST https://console-api.akash.network/v1/deployments \ -H "x-api-key: $AKASH_API_KEY" \ -H "Content-Type: application/json" \ -d '{"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({ sdl: YOUR_SDL_STRING }),});const { dseq } = await res.json();Response:
{ "dseq": "1234567", "status": "active", "createdAt": "2024-01-15T10:30:00Z"}2. Wait for and Fetch Bids
List bids for your deployment. Bids typically arrive within 30-60 seconds.
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 bids = await res.json();Response:
[ { "id": "bid_abc123", "provider": "akash1abc...xyz", "price": "0.50", "denom": "usd", "status": "open" }]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 bids = await res.json(); if (bids.length > 0) return bids; await new Promise((r) => setTimeout(r, pollMs)); } throw new Error("No bids received within timeout");}3. Create Lease
Accept a bid to activate the deployment lease.
cURL:
curl -X POST https://console-api.akash.network/v1/leases \ -H "x-api-key: $AKASH_API_KEY" \ -H "Content-Type: application/json" \ -d '{"dseq": "1234567", "bidId": "bid_abc123"}'JavaScript (fetch):
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({ dseq, bidId }),});const lease = await res.json();Response:
{ "leaseId": "lease_xyz789", "dseq": "1234567", "provider": "akash1abc...xyz", "status": "active"}4. Add Deposit to Deployment
Add funds to extend deployment runtime.
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 '{"dseq": "1234567", "amount": "10.00"}'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({ dseq, amount: "10.00" }),});const depositResult = await res.json();Response:
{ "dseq": "1234567", "depositedAmount": "10.00", "newBalance": "14.73"}5. Close Deployment
Close a deployment and recover remaining escrow funds.
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 closeResult = await res.json();Response:
{ "dseq": "1234567", "status": "closed", "refundedAmount": "4.50", "closedAt": "2024-01-16T12:00:00Z"}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 response = await apiRequest(`/v1/bids?dseq=${dseq}`, { method: "GET", headers: { "Content-Type": "application/json" }, });
// Current API shape returns bids under response.data. if (response.data?.length > 0) return response.data; await new Promise((resolve) => setTimeout(resolve, pollMs)); } throw new Error("No bids received within timeout");}
async function main() { const created = await apiRequest("/v1/deployments", { method: "POST", body: JSON.stringify({ sdl: SDL }), }); const dseq = created.dseq || created.data?.dseq; if (!dseq) throw new Error("Missing dseq in create deployment response");
const bids = await waitForBids(dseq); const firstBid = bids[0]; const bidId = firstBid?.id || firstBid?.bid?.id; if (!bidId) throw new Error("Missing bid identifier in bids response");
await apiRequest("/v1/leases", { method: "POST", body: JSON.stringify({ dseq, bidId }), });
await apiRequest("/v1/deposit-deployment", { method: "POST", body: JSON.stringify({ dseq, amount: "10.00" }), });
const status = await apiRequest(`/v1/deployments/${dseq}`, { method: "GET" }); 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);});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.CONSOLE_API_KEY;
// **Bad: Hardcoded keyconst API_KEY = "akt_abc123...";Error Handling
Use HTTP status codes to determine recovery behavior.
| Status | Meaning | Common cause |
|---|---|---|
| 200 OK | Request succeeded | - |
| 201 Created | Resource created | POST to /v1/deployments, /v1/leases, /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 |
| 409 Conflict | State conflict | Lease already exists for this deployment |
| 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
- Full API Documentation - Complete API reference on GitHub
- Example Script - Working implementation
- SDL Reference - SDL syntax guide
- Console Documentation - Console overview
Need Help?
- Discord: discord.akash.network
- GitHub Issues: console/issues
- Support: GitHub Support