Console API reference

The Akash Console API is a thin, REST-ish layer over the underlying chain. Every endpoint takes JSON in, returns JSON out, and authenticates with an x-api-key header. Pick a language on the right — every sample on this page updates to match.

Base URL
https://console-api.akash.network
Version
v1
Auth
x-api-key header

Authentication

Every request must include the x-api-key header. Create and manage keys in Console under Settings → API Keys.

Authentication errors return 401 Unauthorized with { "error": "Unauthorized", "message": "Invalid API key" }.

GET /v1/deployments HTTP/1.1
Host: console-api.akash.network
x-api-key: YOUR_API_KEY

# 401 response when the key is missing or invalid:
{ "error": "Unauthorized", "message": "Invalid API key" }
GET /v1/deployments HTTP/1.1
Host: console-api.akash.network
x-api-key: YOUR_API_KEY

# 401 response when the key is missing or invalid:
{ "error": "Unauthorized", "message": "Invalid API key" }

Response envelope

Every JSON response is wrapped in a top-level data field. For list endpoints, data carries both the array and a pagination object.

# Single resource:
{ "data": { "...": "..." } }

# List resource:
{ "data": { "deployments": [ ... ], "pagination": { ... } } }
# Single resource:
{ "data": { "...": "..." } }

# List resource:
{ "data": { "deployments": [ ... ], "pagination": { ... } } }

Errors

The API uses standard HTTP status codes. All error responses share the same JSON shape.

HTTPCode stringDescription
400BadRequestThe request body or query parameters are invalid. Check message for details.
401Unauthorizedx-api-key is missing, expired, or invalid.
404NotFoundThe resource (dseq) does not exist or is not owned by the authenticated user.
429TooManyRequestsRequest rate exceeded. Wait before retrying.
500InternalServerErrorUnexpected server error. Retry with exponential backoff.
# Error response schema:
{ "error": "string", "message": "string" }
# Error response schema:
{ "error": "string", "message": "string" }

API Versioning

Endpoints are prefixed with a version number (/v1/ or /v2/). Versions are independent — upgrading one endpoint version does not affect others.

VersionStatusEndpoints
v1StableDeployments, bids, leases, deposit
v2StableDeployment settings (auto top-up)

Future breaking changes are introduced as a new version prefix; prior versions remain available for a deprecation period announced in the changelog.

Pagination

GET /v1/deployments uses offset-based pagination via skip and limit. The response includes a pagination object with total, skip, limit, and hasMore so you can drive a paging loop without guessing when to stop.

ParameterTypeDefaultMinimumDescription
skipinteger00Number of records to skip (offset)
limitinteger10001Maximum records to return per page
# Stream every page sequentially:
SKIP=0
LIMIT=100
while :; do
  curl -s "https://console-api.akash.network/v1/deployments?skip=$SKIP&limit=$LIMIT" \
    -H "x-api-key: $AKASH_API_KEY" > page.json
  jq -e '.data.pagination.hasMore' page.json > /dev/null || break
  SKIP=$((SKIP + LIMIT))
done
# Stream every page sequentially:
SKIP=0
LIMIT=100
while :; do
  curl -s "https://console-api.akash.network/v1/deployments?skip=$SKIP&limit=$LIMIT" \
    -H "x-api-key: $AKASH_API_KEY" > page.json
  jq -e '.data.pagination.hasMore' page.json > /dev/null || break
  SKIP=$((SKIP + LIMIT))
done

POST /v1/deployments

Create a new deployment from an SDL manifest and fund its escrow.

Parameter Description
x-api-key header string required
Your API key
data.sdl body string required
Deployment manifest in SDL (YAML) format, as a JSON string
data.deposit body number required
Initial escrow deposit in USD. Minimum 0.5

Response 201 Created

Field Description
data.dseq string
Deployment sequence ID
data.manifest string
Rendered manifest blob to send with POST /v1/leases
data.signTx.code number
Cosmos tx code (0 = success)
data.signTx.transactionHash string
Broadcast transaction hash
data.signTx.rawLog string
Raw chain log
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": "version: \"2.0\"\n...", "deposit": 0.5 } }'
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": "version: \"2.0\"\n...", "deposit": 0.5 } }'

GET /v1/bids

List provider bids for a deployment. Poll until bids arrive.

Parameter Description
x-api-key header string required
Your API key
dseq query string required
Deployment sequence ID returned by create deployment

Response 200 OK

Field Description
data[].bid.id.owner string
Owner address
data[].bid.id.dseq string
Deployment sequence ID
data[].bid.id.gseq number
Group sequence
data[].bid.id.oseq number
Order sequence
data[].bid.id.provider string
Provider address
data[].bid.id.bseq number
Bid sequence (chain height)
data[].bid.state string
Bid state (e.g. open)
data[].bid.price.denom string
Chain denom (e.g. uact)
data[].bid.price.amount string
Chain amount in micro-units, per block
data[].bid.created_at string
Chain height at creation
data[].bid.resources_offer array
Offered CPU / memory / storage / GPU / endpoints
data[].escrow_account object
Provider's bid escrow account
There is no flat bid.id string — the bid is identified by the composite {owner, dseq, gseq, oseq, provider, bseq}. When creating a lease, copy dseq, gseq, oseq, and provider from this object.
While bids are pending, the endpoint returns { "data": [] }. Poll every few seconds.
curl "https://console-api.akash.network/v1/bids?dseq=1234567" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/bids?dseq=1234567" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v1/leases

Accept one or more provider bids and ship the manifest in a single call.

Parameter Description
x-api-key header string required
Your API key
manifest body string required
Manifest blob returned by POST /v1/deployments
leases body array required
One entry per bid to accept
leases[].dseq body string required
Deployment sequence ID
leases[].gseq body number required
Group sequence (from bid.id.gseq)
leases[].oseq body number required
Order sequence (from bid.id.oseq)
leases[].provider body string required
Provider address (from bid.id.provider)

Response 200 OK

Response is the full deployment object — same shape as GET /v1/deployments/{dseq}.
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>",
    "leases": [
      { "dseq": "1234567", "gseq": 1, "oseq": 1, "provider": "akash1provider..." }
    ]
  }'
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>",
    "leases": [
      { "dseq": "1234567", "gseq": 1, "oseq": 1, "provider": "akash1provider..." }
    ]
  }'

POST /v1/deposit-deployment

Add USD funds to a deployment's escrow to extend its runtime.

Parameter Description
x-api-key header string required
Your API key
data.dseq body string required
Deployment sequence ID
data.deposit body number required
Deposit amount in USD. Minimum 0.5

Response 200 OK

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 } }'
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 } }'

GET /v1/deployments

List all deployments for the authenticated user, with pagination.

Parameter Description
x-api-key header string required
Your API key
skip query integer
Offset. Default 0
limit query integer
Max records. Default 1000

Response 200 OK

Field Description
data.deployments[] array
One entry per deployment, same shape as GET /v1/deployments/{dseq} minus per-lease status
data.pagination.total number
Total deployments for the user
data.pagination.skip number
Skip value used
data.pagination.limit number
Limit value used
data.pagination.hasMore boolean
True when more pages are available
curl "https://console-api.akash.network/v1/deployments?skip=0&limit=10" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/deployments?skip=0&limit=10" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/deployments/{dseq}

Retrieve full details for a single deployment by its sequence ID.

Parameter Description
x-api-key header string required
Your API key
dseq path string required
Deployment sequence ID

Response 200 OK

Field Description
data.deployment.id.owner string
Owner address
data.deployment.id.dseq string
Deployment sequence ID
data.deployment.state string
Deployment state (active, closed)
data.deployment.hash string
Manifest hash
data.deployment.created_at string
Chain height at creation
data.leases[] array
Active leases (composite id + state, price, created_at, closed_on, status)
data.escrow_account object
Deployment escrow account with funds[], deposits[], transferred[] (raw chain denoms)
curl "https://console-api.akash.network/v1/deployments/1234567" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/deployments/1234567" \
  -H "x-api-key: $AKASH_API_KEY"

PUT /v1/deployments/{dseq}

Update an active deployment with a revised SDL.

Parameter Description
x-api-key header string required
Your API key
dseq path string required
Deployment sequence ID
data.sdl body string required
Updated SDL in YAML format, passed as a JSON string

Response 200 OK

curl -X PUT "https://console-api.akash.network/v1/deployments/1234567" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "sdl": "version: \"2.0\"\n..." } }'
curl -X PUT "https://console-api.akash.network/v1/deployments/1234567" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "sdl": "version: \"2.0\"\n..." } }'

DELETE /v1/deployments/{dseq}

Close a deployment. Remaining escrow is returned asynchronously by the chain to your Console balance.

Parameter Description
x-api-key header string required
Your API key
dseq path string required
Deployment sequence ID to close

Response 200 OK

curl -X DELETE "https://console-api.akash.network/v1/deployments/1234567" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X DELETE "https://console-api.akash.network/v1/deployments/1234567" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v2/deployment-settings/{dseq}

Get auto top-up settings for a specific deployment. Settings are auto-created on first read.

Parameter Description
x-api-key header string required
Your API key
dseq path string required
Deployment sequence number
userId query string
Defaults to authenticated user

Response 200 OK

Field Description
data.id string (uuid)
Setting record id
data.userId string
Owning user id
data.dseq string
Deployment sequence number
data.autoTopUpEnabled boolean
Whether auto top-up is enabled
data.estimatedTopUpAmount number
Estimated top-up amount per cycle (USD)
data.topUpFrequencyMs number
Top-up cadence in milliseconds
data.createdAt string
ISO-8601 creation time
data.updatedAt string
ISO-8601 last update time
curl "https://console-api.akash.network/v2/deployment-settings/1234567" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v2/deployment-settings/1234567" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v2/deployment-settings

Create deployment settings (typically used to enable auto top-up when the settings row does not yet exist).

Parameter Description
x-api-key header string required
Your API key
data.dseq body string required
Deployment sequence number
data.autoTopUpEnabled body boolean required
Enable or disable automatic top-up
data.userId body string (uuid)
Defaults to authenticated user

Response 201 Created

curl -X POST https://console-api.akash.network/v2/deployment-settings \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "dseq": "1234567", "autoTopUpEnabled": true } }'
curl -X POST https://console-api.akash.network/v2/deployment-settings \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "dseq": "1234567", "autoTopUpEnabled": true } }'

PATCH /v2/deployment-settings/{dseq}

Update an existing settings row.

Parameter Description
x-api-key header string required
Your API key
dseq path string required
Deployment sequence number
userId query string (uuid)
Defaults to authenticated user
data.autoTopUpEnabled body boolean required
Enable or disable automatic top-up

Response 200 OK

curl -X PATCH https://console-api.akash.network/v2/deployment-settings/1234567 \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "autoTopUpEnabled": false } }'
curl -X PATCH https://console-api.akash.network/v2/deployment-settings/1234567 \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "autoTopUpEnabled": false } }'

JWT for provider access

JWT for provider access

The Console API and the provider share a JWT-based access model for lease-scoped operations (logs, events, status, shell). Mint a short-lived token from the Console API, then call the provider directly with it.

TTL: tokens are short-lived (default 1800 s in the Console UI). There is no refresh endpoint — re-call POST /v1/create-jwt-token to extend lifetime.

Scope: grant the narrowest set you need. Missing scope → 401 from the provider. Valid values: send-manifest, get-manifest, logs, shell, events, status, restart, hostname-migrate, ip-migrate.

Spec: JWT payload follows AEP-64. The provider validates it the same way regardless of who minted it.

Stability: POST /v1/create-jwt-token is Swagger-only / Tier 2 — observed in production but not in the official API reference. It may change without notice. Self-custody users sign locally with @akashnetwork/chain-sdk and bypass this endpoint entirely.

POST /v1/create-jwt-token

Mint a short-lived, lease-scoped JWT for accessing provider endpoints.

Parameter Description
x-api-key header string required
Your API key
data.ttl body number required
Token TTL in seconds (Console UI default: 1800)
data.leases.access body enum required
One of full, scoped, or granular
data.leases.scope body array<string>
Required when access is scoped. Any of send-manifest, get-manifest, logs, shell, events, status, restart, hostname-migrate, ip-migrate
data.leases.permissions body array<object>
Required when access is granular. Per-provider, per-deployment rules

Response 201 Created

Field Description
data.token string (JWT)
Bearer token to send to provider endpoints as Authorization: Bearer
Swagger-only / Tier 2 endpoint — may change without notice.
No refresh endpoint exists. To extend a token's lifetime, re-call this endpoint and discard the old token.
JWT=$(curl -sX POST https://console-api.akash.network/v1/create-jwt-token \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "ttl": 1800,
      "leases": {
        "access": "scoped",
        "scope": ["status", "logs", "events", "shell"]
      }
    }
  }' | jq -r .data.token)
JWT=$(curl -sX POST https://console-api.akash.network/v1/create-jwt-token \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "ttl": 1800,
      "leases": {
        "access": "scoped",
        "scope": ["status", "logs", "events", "shell"]
      }
    }
  }' | jq -r .data.token)

Lease operations (provider)

Provider-side lease endpoints

These endpoints are served by the provider, not by console-api.akash.network. Resolve the provider's hostUri via GET /v1/providers/{address} (network-data API), then call the provider directly with the JWT in Authorization: Bearer <token>.

TLS / cert pinning: provider certificates are self-signed against the provider's on-chain wallet address — browsers will reject them. Server-side, you have to look the cert up on-chain: the CN must be the provider's bech32 wallet address, and the chain's MsgCreateCertificate record for that (address, serial number) must match the leaf cert's fingerprint. That lookup is a chain query, so it has to happen after the TLS handshake — Node's checkServerIdentity is synchronous and can't await. The canonical pattern (used by Console) is to disable Node's default verification, then validate the peer cert asynchronously against the chain. See the provider-proxy CertificateValidator for a reference implementation. In a browser, route through a provider-proxy service.

events vs kubeevents gotcha: Console UI accepts events as a path component and rewrites it to kubeevents client-side. The wire path on the provider is always kubeevents — use that directly to avoid surprises.

Common errors:

  • 401 — JWT scope doesn't include the requested operation (e.g. calling /logs without logs in scope).
  • Empty log stream — the deployment hasn't started yet, or the named service isn't running.
  • TLS handshake failure — you're missing the cert-pinning agent, or the provider has rotated keys.

GET https://{hostUri}/lease/{dseq}/{gseq}/{oseq}/status Provider

Polled status of each service in a lease: ready/total replicas, forwarded ports, IPs, restart counts.

Parameter Description
Authorization header string required
Bearer
dseq path string required
Deployment sequence ID
gseq path number required
Group sequence
oseq path number required
Order sequence

Response 200 OK

Field Description
services.<name>.ready_replicas number
Replicas currently passing readiness checks
services.<name>.available_replicas number
Replicas marked available by the Kubernetes controller
services.<name>.replicas number
Current replicas
services.<name>.total number
Desired replicas
services.<name>.uris array<string>
Accessible URIs for the service (when leasing endpoints)
forwarded_ports.<name> array<object>
Provider-side port forwards, keyed by service name (top-level — not nested under services)
ips.<name> array<object>
Public IPs assigned to the service, keyed by service name (top-level, when leasing IP endpoints)
Same shape as deployment.leases[].status in the Console API, but freshly polled from the provider.
JWT scope must include status.
# -k skips TLS verification (provider certs are self-signed against the
# on-chain wallet). For production, validate the cert against the chain
# out-of-band — see the provider-endpoints preface.
curl -k "https://${HOSTURI#https://}/lease/${DSEQ}/${GSEQ}/${OSEQ}/status" \
  -H "Authorization: Bearer $JWT"
# -k skips TLS verification (provider certs are self-signed against the
# on-chain wallet). For production, validate the cert against the chain
# out-of-band — see the provider-endpoints preface.
curl -k "https://${HOSTURI#https://}/lease/${DSEQ}/${GSEQ}/${OSEQ}/status" \
  -H "Authorization: Bearer $JWT"

WSS wss://{hostUri}/lease/{dseq}/{gseq}/{oseq}/logs Provider

Stream container logs for a lease. Send follow=true to tail continuously.

Parameter Description
Authorization header string required
Bearer (scope must include logs)
dseq path string required
Deployment sequence ID
gseq path number required
Group sequence
oseq path number required
Order sequence
tail query number
Number of lines to tail from the end of the log
follow query boolean
Stream new logs continuously when true
service query string
Filter to a specific service name
Field Description
(stream) binary
Stream of text chunks; one chunk ≈ one log line
JWT scope must include logs.
In a browser, the self-signed provider cert will be rejected — route through a provider-proxy.
# --insecure skips TLS verification (provider certs are self-signed).
# Requires websocat 1.13+. See provider-endpoints preface for production
# cert validation.
websocat --insecure "wss://${HOSTURI#https://}/lease/${DSEQ}/${GSEQ}/${OSEQ}/logs?follow=true&tail=200" \
  -H "Authorization: Bearer $JWT"
# --insecure skips TLS verification (provider certs are self-signed).
# Requires websocat 1.13+. See provider-endpoints preface for production
# cert validation.
websocat --insecure "wss://${HOSTURI#https://}/lease/${DSEQ}/${GSEQ}/${OSEQ}/logs?follow=true&tail=200" \
  -H "Authorization: Bearer $JWT"

WSS wss://{hostUri}/lease/{dseq}/{gseq}/{oseq}/kubeevents Provider

Stream Kubernetes events for the lease (pod scheduling, container restarts, etc.).

Parameter Description
Authorization header string required
Bearer (scope must include events)
dseq path string required
Deployment sequence ID
gseq path number required
Group sequence
oseq path number required
Order sequence
Field Description
(stream) JSON objects
One Kubernetes Event per message frame
The wire path is kubeevents, not events. Some client tools accept events and rewrite it client-side, but the provider only responds on kubeevents.
JWT scope must include events.
# --insecure skips TLS verification (provider certs are self-signed).
websocat --insecure "wss://${HOSTURI#https://}/lease/${DSEQ}/${GSEQ}/${OSEQ}/kubeevents" \
  -H "Authorization: Bearer $JWT"
# --insecure skips TLS verification (provider certs are self-signed).
websocat --insecure "wss://${HOSTURI#https://}/lease/${DSEQ}/${GSEQ}/${OSEQ}/kubeevents" \
  -H "Authorization: Bearer $JWT"

WSS wss://{hostUri}/lease/{dseq}/{gseq}/{oseq}/shell Provider

Interactive kubectl exec-style shell. Binary multiplexed stream of stdin/stdout/stderr/resize. Advanced — prefer the SDK helpers for most use cases.

Parameter Description
Authorization header string required
Bearer (scope must include shell)
dseq path string required
Deployment sequence ID
gseq path number required
Group sequence
oseq path number required
Order sequence
service query string required
Service name to exec into
podIndex query number required
Pod index (zero-based)
tty query number required
1 to allocate a TTY, 0 otherwise
stdin query number required
1 to attach stdin, 0 otherwise
cmd0, cmd1, … query string required
Command and each argument as separate numbered params, e.g. cmd0=/bin/sh&cmd1=-c&cmd2=ls. There is no single (or base64) cmd param.
Field Description
(stream) binary
Multiplexed binary frames; the first byte is the stream code — 100=stdout, 101=stderr, 102=result (JSON, e.g. {\"exit_code\":0}), 103=failure. Client→server uses 104=stdin, 105=terminal-resize.
JWT scope must include shell.
Command and arguments are passed as separate numbered query params (cmd0, cmd1, …) — there is no single base64-encoded cmd param. tty and stdin are required.
The example above is a one-shot command (tty=0&stdin=0). For an interactive session, set tty=1&stdin=1, stream keystrokes as 104-prefixed binary frames, and send terminal resizes as 105 frames. Most users should use the Akash CLI (provider-services lease-shell --tty) or SDK helpers instead of driving this directly — see Shell Access.
Console UI uses xterm.js on the client side to render the stream.
For programmatic shells, use the provider's kubectl exec-style protocol via the SDK helpers rather than constructing this WebSocket by hand.

See also