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" }.

A key acts in the account it was created in, your personal account or a team, with your role there, and can be limited to one project. See Organizations and projects.

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.
403ForbiddenYour role, the key's project, or a project budget does not allow the request.
404NotFoundThe resource (dseq) does not exist or is out of the caller's reach.
429TooManyRequestsRequest rate exceeded. Wait before retrying.
500InternalServerErrorUnexpected server error. Retry with exponential backoff.

code names the precise reason, such as project_forbidden or project_budget_exceeded. The organization and project codes are listed under Organizations and projects.

# Error response schema:
{ "error": "string", "message": "string", "code": "string", "type": "string" }
# Error response schema:
{ "error": "string", "message": "string", "code": "string", "type": "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
v2StableDeployment settings (runtime limit)

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.

ParameterTypeDefaultMinimumMaximumDescription
skipinteger00noneNumber of records to skip (offset)
limitinteger1001100Maximum 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. Console funds it automatically from your account credits, so the request takes no deposit.

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. May include a params.tee field (cpu/cpu-gpu) to request Confidential Compute
data.runtimeLimitHours body number
Close the deployment after this many hours of runtime, counted from lease start. Omit for always-on funding
data.projectId body string (uuid)
Project of the organization to file the deployment in. Omit it to use the only project you can deploy into, otherwise the organization's default project

Response 201 Created

Field Description
data.dseq string
Deployment sequence ID
data.manifest string
Rendered manifest. You don't need to keep it: POST /v1/leases sends the provider a manifest built from the SDL Console recorded
data.signTx.code number
Cosmos tx code (0 = success)
data.signTx.transactionHash string
Broadcast transaction hash
data.signTx.rawLog string
Raw chain log
Request Confidential Compute (TEE) by adding a params.tee field (cpu or cpu-gpu) to a service in the SDL — cpu-gpu requires GPU resources. See Confidential Compute (TEE).
400 with code project_required means no project you can deploy into was found: pass data.projectId or x-project-id. 403 with code project_budget_exceeded means the deposit would take the project past its monthly budget, and nothing was created. 503 with code deposit_price_unavailable means the deposit could not be priced against the project's budget; it is transient, so retry. An unknown projectId answers 404.
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..." } }'
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..." } }'

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. Console creates the leases, then sends each provider the manifest built from the SDL it recorded when the deployment was created, so the request carries only the bids.

Parameter Description
x-api-key header string required
Your API key
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)
manifest body string
**Deprecated.** Leave it out: Console builds the manifest from the SDL it recorded

Response 200 OK

Response is the full deployment object — same shape as GET /v1/deployments/{dseq}.
A 502 with code provider_unreachable means no lease was created, so pick another bid. With code manifest_not_delivered the lease exists but the provider didn't take the manifest: send the same request again to retry, or close the deployment to stop paying for it.
curl -X POST https://console-api.akash.network/v1/leases \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "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 '{
    "leases": [
      { "dseq": "1234567", "gseq": 1, "oseq": 1, "provider": "akash1provider..." }
    ]
  }'

POST /v1/deposit-deployment

Deprecated. Console funds every deployment automatically for as long as your account has credits, so there is nothing for this endpoint to do. It still accepts requests so existing integrations keep working, and will be removed in a future release.

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. Accepted but no longer needed

Response 200 OK

Replaced by automatic funding. Add credits to your account instead. See How Funding Works.
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
Records per page, from 1 to 100. Default 100
state query string
active (default) or closed
search query string
Case-insensitive match against each deployment's name and dseq
reverse query string
true lists the newest deployment first. Default false (oldest first)
projectId query string (uuid)
Only the deployments filed in this project. A project you cannot reach lists nothing

Response 200 OK

Field Description
data.deployments[] array
One entry per deployment, same shape as GET /v1/deployments/{dseq} minus per-lease status
data.deployments[].projectId string | null
Project the deployment is filed in
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"

PATCH /v1/deployments/{dseq}

Change a running deployment in place: a service's image, command, arguments, environment variables, registry credentials, exposed ports or volume mounts, or the deployment's name. Console applies the patch to the SDL it recorded at create, so the request never carries an SDL, and only the services you name change.

Parameter Description
x-api-key header string required
Your API key
dseq path string required
Deployment sequence ID
data.services.<name>.image body string
New image for the service, with an explicit tag
data.services.<name>.env body object
Merged into the service's env by variable name. null removes a variable
data.services.<name>.command body array
Replaces the container command
data.services.<name>.args body array
Replaces the command arguments
data.services.<name>.credentials body object
Private registry host, username and password. null clears them
data.services.<name>.expose.<port> body object
Keyed by the container port the SDL declares: port, as, accept (custom domains) and httpOptions
data.services.<name>.storage.<volume> body object
mount and readOnly only. Sizes are fixed at create
data.name body string
Renames the deployment
data.sealedSecrets body string
Compact JWE holding only the secret values this patch replaces, for env values written as ac-secret://NAME
data.ifManifestVersion body string
Base64 manifest version you expect to be current. Answers 409 if the deployment has moved on

Response 200 OK

Field Description
data.deployment object
The deployment, as in GET /v1/deployments/{dseq}
data.leases array
Its leases
data.name string
Deployment name
data.manifestVersion string
Base64 version of the manifest now current. Pass it as ifManifestVersion on the next patch
Compute resources, replica counts, groups and globally exposed ports are fixed at create. A patch that would change them answers 422 with code deployment_resources_changed; create a new deployment instead.
404 means Console holds no recorded SDL for this deployment, so there is nothing to patch.
409 with code deployment_definition_changed means another change landed between this patch reading the deployment and writing it. Reload it and retry.
curl -X PATCH "https://console-api.akash.network/v1/deployments/1234567" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "services": {
        "web": {
          "image": "nginx:1.27.3",
          "env": { "LOG_LEVEL": "debug", "OLD_FLAG": null }
        }
      }
    }
  }'
curl -X PATCH "https://console-api.akash.network/v1/deployments/1234567" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "services": {
        "web": {
          "image": "nginx:1.27.3",
          "env": { "LOG_LEVEL": "debug", "OLD_FLAG": null }
        }
      }
    }
  }'

PUT /v1/deployments/{dseq}

Deprecated. Resubmits the whole SDL. Use PATCH /v1/deployments/{dseq} instead; this endpoint will be removed in a future release.

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

Refused with 422 and code deployment_resources_changed when the SDL changes the groups, compute resources, replica counts or globally exposed ports the deployment was created with.
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. Whatever it has not yet spent returns to your Console account balance once the chain settles.

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 the funding settings for a specific deployment, including its runtime limit. 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
Always true. Automatic funding cannot be turned off
data.estimatedTopUpAmount number
Estimated top-up amount per cycle (USD)
data.topUpFrequencyMs number
Top-up cadence in milliseconds
data.runtimeLimitHours number \| null
Runtime limit in hours chosen at creation, or null for always-on funding
data.runtimeEndsAt string \| null
When the runtime limit is reached, anchored at lease start; null until the lease starts or when no limit is set
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 the settings row for a deployment when it does not yet exist. Automatic funding is on by default and cannot be turned off.

Parameter Description
x-api-key header string required
Your API key
data.dseq body string required
Deployment sequence number
data.autoTopUpEnabled body boolean
Defaults to true when omitted. An explicit false is rejected
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. Use this to set, extend, or remove a deployment's runtime limit.

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
An explicit false is rejected
data.runtimeLimitHours body number \| null
New total runtime limit in hours, counted from lease start. Send null to remove the limit and return the deployment to always-on funding. Lowering a limit is not supported

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": { "runtimeLimitHours": 48 } }'
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": { "runtimeLimitHours": 48 } }'

Organizations and projects

Organizations and projects

Every request runs in one organization, your personal account or a team, and can be limited to one project of it. An API key acts in the organization it was created in, with your role there, and can be limited to one project. See Organizations and Projects through the API for a walkthrough.

HeaderDescription
x-organization-idId or slug of the organization. Optional with an API key, which already decides it: naming another organization answers 400 organization_mismatch.
x-project-idLimits the request to one project of the organization. A project out of your reach answers 403 project_forbidden.

Owners and admins reach every project. Members and viewers reach every project or only the ones granted to them, and billing members reach none. Each endpoint below says who may call it.

HTTPcodeMeaning
400organization_mismatchx-organization-id names another organization than the API key's.
403organization_forbiddenThe caller is not a member of the organization, for example after leaving it.
403project_forbiddenx-project-id names a project out of reach or other than the key's, or the deployment is filed in a project the caller cannot change.
400project_requiredNo project the caller can deploy into was named.
403project_budget_exceededThe deposit would take the project past its monthly budget. data.projectIds lists the projects.
403project_limit_reachedThe organization already has 10 projects, the default one included. data.limit holds the limit.
403organization_limit_reachedThe caller already has 3 organizations they created, the most one person can have. data.limit holds the limit.
403session_requiredThe action needs a signed-in Console session.

Reading a project, deployment, budget or grant outside the caller's reach answers 404, the same as one that does not exist.

Creating an organization (POST /v1/organizations), deleting it (DELETE /v1/organizations/{id}), leaving it (DELETE /v1/organizations/{id}/membership) and accepting an invitation (POST /v1/invitations/accept) need a signed-in Console session, so an API key gets 403 session_required. Do those in Console.

# List the deployments of one project
curl "https://console-api.akash.network/v1/deployments" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "x-project-id: 7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b"
# List the deployments of one project
curl "https://console-api.akash.network/v1/deployments" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "x-project-id: 7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b"

GET /v1/organizations

List the organizations of the caller and their role in each. With an API key, the list holds only the key's organization.

Parameter Description
x-api-key header string required
Your API key

Response 200 OK

Field Description
data[].id string (uuid)
Organization id
data[].name string
Organization name
data[].slug string
Slug, accepted by x-organization-id like the id
data[].type string
personal or team
data[].role string
The caller's role: owner, admin, member, billing or viewer
data[].isActive boolean
Whether this request ran in this organization
data[].hasPaymentMethod boolean | null
Whether the organization has a card saved. Null for one the request did not run in
data[].createdAt string
ISO-8601 creation time
curl "https://console-api.akash.network/v1/organizations" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/organizations" \
  -H "x-api-key: $AKASH_API_KEY"

PATCH /v1/organizations/{id}

Rename the active team organization. Owners and admins only.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Id of the active organization
data.name body string required
New name, unique among the organizations the caller belongs to

Response 200 OK

403 with code personal_organization for a personal account. 409 with code organization_name_taken when the caller already belongs to an organization with this name.
curl -X PATCH "https://console-api.akash.network/v1/organizations/0b6c3f9e-8f1a-4d2b-9c7e-1a2b3c4d5e6f" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "Acme Platform"
    }
  }'
curl -X PATCH "https://console-api.akash.network/v1/organizations/0b6c3f9e-8f1a-4d2b-9c7e-1a2b3c4d5e6f" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "Acme Platform"
    }
  }'

GET /v1/organization-members

List the members of the active organization. Every member may call it.

Parameter Description
x-api-key header string required
Your API key

Response 200 OK

Field Description
data[].id string (uuid)
Membership id, used by the member endpoints below
data[].userId string (uuid)
User id, used to grant project access
data[].username string | null
Username
data[].email string | null
Email address
data[].role string
owner, admin, member, billing or viewer
data[].projectAccess string | null
all or selected for members and viewers, all for owners and admins, null for billing members
data[].projectCount number | null
Projects granted to a member or viewer on selected
data[].createdAt string
When they joined
curl "https://console-api.akash.network/v1/organization-members" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/organization-members" \
  -H "x-api-key: $AKASH_API_KEY"

PATCH /v1/organization-members/{id}

Change a member's role, project access and project grants, all together or not at all. Owners and admins; only an owner can change anything about the owner role.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Membership id from GET /v1/organization-members
data.role body string
owner, admin, member, billing or viewer
data.projectAccess body string
all or selected. Required when someone becomes a member or viewer from another role
data.projectGrants body array
[{ projectId, role }] with role viewer, member or admin. Replaces every grant of a member or viewer on selected

Response 200 OK

Send at least one field. A member or viewer on selected needs at least one grant.
400 with code project_access_required when someone becomes a member or viewer without projectAccess. 403 with code owner_role_restricted when a non-owner touches the owner role. 409 with code last_owner when the organization would be left without an owner.
curl -X PATCH "https://console-api.akash.network/v1/organization-members/5a8b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "role": "member",
      "projectAccess": "selected",
      "projectGrants": [
        {
          "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b",
          "role": "admin"
        }
      ]
    }
  }'
curl -X PATCH "https://console-api.akash.network/v1/organization-members/5a8b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "role": "member",
      "projectAccess": "selected",
      "projectGrants": [
        {
          "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b",
          "role": "admin"
        }
      ]
    }
  }'

DELETE /v1/organization-members/{id}

Remove a member from the active organization. Their access, and the API keys they created in it, stop working. Owners and admins; only an owner can remove an owner.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Membership id

Response 204 No Content

409 with code last_owner when the organization would be left without an owner.
curl -X DELETE "https://console-api.akash.network/v1/organization-members/5a8b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X DELETE "https://console-api.akash.network/v1/organization-members/5a8b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v1/organization-members/{id}/ownership-transfer

Make a member an owner of the active organization and step the calling owner down to admin. Owners only.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Membership id of the new owner

Response 200 OK

curl -X POST "https://console-api.akash.network/v1/organization-members/5a8b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d/ownership-transfer" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X POST "https://console-api.akash.network/v1/organization-members/5a8b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d/ownership-transfer" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/organization-members/{id}/project-grants

List the projects a member is granted, with the role on each. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Membership id

Response 200 OK

Field Description
data[].projectId string (uuid)
Granted project
data[].role string
viewer, member or admin
curl "https://console-api.akash.network/v1/organization-members/5a8b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d/project-grants" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/organization-members/5a8b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d/project-grants" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/organization-invitations

List the pending invitations of the active organization. Owners and admins.

Parameter Description
x-api-key header string required
Your API key

Response 200 OK

Field Description
data[].id string (uuid)
Invitation id
data[].email string
Invited address
data[].role string
Role the invitation grants
data[].projectAccess string
all or selected
data[].projectGrants array
[{ projectId, role }] granted on joining
data[].invitedBy object | null
{ id, username } of the inviter
data[].expiresAt string
When the link stops working, 7 days after it was sent
curl "https://console-api.akash.network/v1/organization-invitations" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/organization-invitations" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v1/organization-invitations

Invite people to the active team by email. Each address gets an email with a link, valid for 7 days, that they accept in Console. Owners and admins; only an owner can invite an owner.

Parameter Description
x-api-key header string required
Your API key
data.emails body array<string> required
1 to 20 addresses
data.role body string required
owner, admin, member, billing or viewer
data.projectAccess body string
all or selected. For a member or viewer, required unless projectGrants is given
data.projectGrants body array
[{ projectId, role }] for a member or viewer on selected

Response 201 Created

400 with code project_access_required for a member or viewer with neither projectAccess nor grants. 409 with code already_member when an address belongs to a member. 403 with code invitation_limit_reached when the organization has too many pending invitations, and 429 with code invitation_email_limit_reached when too many invitation emails were sent recently.
curl -X POST "https://console-api.akash.network/v1/organization-invitations" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "emails": [
        "[email protected]"
      ],
      "role": "member",
      "projectAccess": "selected",
      "projectGrants": [
        {
          "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b",
          "role": "member"
        }
      ]
    }
  }'
curl -X POST "https://console-api.akash.network/v1/organization-invitations" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "emails": [
        "[email protected]"
      ],
      "role": "member",
      "projectAccess": "selected",
      "projectGrants": [
        {
          "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b",
          "role": "member"
        }
      ]
    }
  }'

POST /v1/organization-invitations/{id}/resend

Email a pending invitation again, with a new link and a new expiry. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Invitation id

Response 200 OK

curl -X POST "https://console-api.akash.network/v1/organization-invitations/2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978/resend" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X POST "https://console-api.akash.network/v1/organization-invitations/2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978/resend" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v1/organization-invitations/{id}/link

Issue a new link for a pending invitation, to share it yourself. Every earlier link of the invitation stops working. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Invitation id

Response 200 OK

Field Description
data.url string
The invitation link
curl -X POST "https://console-api.akash.network/v1/organization-invitations/2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978/link" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X POST "https://console-api.akash.network/v1/organization-invitations/2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978/link" \
  -H "x-api-key: $AKASH_API_KEY"

DELETE /v1/organization-invitations/{id}

Revoke a pending invitation. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Invitation id

Response 204 No Content

curl -X DELETE "https://console-api.akash.network/v1/organization-invitations/2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X DELETE "https://console-api.akash.network/v1/organization-invitations/2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/projects

List the projects of the active organization the caller can reach, most recently active first.

Parameter Description
x-api-key header string required
Your API key

Response 200 OK

Field Description
data[].id string (uuid)
Project id, for projectId and x-project-id
data[].name string
Name, unique within the organization
data[].slug string
Slug set from the name at creation
data[].description string | null
Description
data[].isDefault boolean
Whether it is the organization's default project
data[].deployments object | null
activeCount and a preview of the newest active deployments. Null when the caller cannot read them
data[].access.canDeploy boolean
Whether the caller may deploy into the project
data[].access.canManage boolean
Whether the caller may rename the project and manage its access
data[].lastActivityAt string
Newest activity the caller may read
curl "https://console-api.akash.network/v1/projects" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/projects" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v1/projects

Create a project in the active organization. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
data.name body string required
Unique within the organization, whatever its case
data.description body string
Optional description

Response 201 Created

409 with code project_name_taken when another project has this name. 403 with code project_limit_reached when the organization already has 10 projects, the default one included; data.limit holds the limit.
curl -X POST "https://console-api.akash.network/v1/projects" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "checkout-api",
      "description": "Payments backend"
    }
  }'
curl -X POST "https://console-api.akash.network/v1/projects" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "checkout-api",
      "description": "Payments backend"
    }
  }'

GET /v1/projects/{id}

Get a project of the active organization the caller can reach.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Project id

Response 200 OK

curl "https://console-api.akash.network/v1/projects/7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/projects/7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b" \
  -H "x-api-key: $AKASH_API_KEY"

PATCH /v1/projects/{id}

Rename a project or change its description. Owners, admins and the project's admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Project id
data.name body string
New name
data.description body string | null
New description, or null to clear it

Response 200 OK

curl -X PATCH "https://console-api.akash.network/v1/projects/7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "payments-api"
    }
  }'
curl -X PATCH "https://console-api.akash.network/v1/projects/7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "payments-api"
    }
  }'

DELETE /v1/projects/{id}

Delete a project that holds no open deployment. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Project id

Response 204 No Content

409 with code project_is_default for the default project, or project_not_empty while it holds open deployments. Close them or move them first.
curl -X DELETE "https://console-api.akash.network/v1/projects/7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X DELETE "https://console-api.akash.network/v1/projects/7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/projects/{id}/members

List who was granted access to a project, and the members and viewers who reach every project.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Project id

Response 200 OK

Field Description
data[] array
Grants on the project: id (grant id), projectId, userId, username, email, role, createdAt
membersWithAllProjects[] array
Members and viewers on all with no grant on this project. Owners and admins are not listed
curl "https://console-api.akash.network/v1/projects/7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b/members" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/projects/7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b/members" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v1/project-members

Grant a member or viewer of the organization a role on a project. Owners, admins and the project's admins.

Parameter Description
x-api-key header string required
Your API key
data.projectId body string (uuid) required
Project id
data.userId body string (uuid) required
userId of a member or viewer, from GET /v1/organization-members
data.role body string required
viewer reads, member also deploys, admin also renames the project and manages its access

Response 201 Created

409 with code already_granted, implicit_project_access (an owner or admin, who reaches every project) or billing_role_not_grantable.
curl -X POST "https://console-api.akash.network/v1/project-members" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b",
      "userId": "9c1d2e3f-4a5b-4c6d-9e7f-8a9b0c1d2e3f",
      "role": "member"
    }
  }'
curl -X POST "https://console-api.akash.network/v1/project-members" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b",
      "userId": "9c1d2e3f-4a5b-4c6d-9e7f-8a9b0c1d2e3f",
      "role": "member"
    }
  }'

PATCH /v1/project-members/{id}

Change the project role a grant gives. Owners, admins and the project's admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Grant id
data.role body string required
viewer, member or admin

Response 200 OK

curl -X PATCH "https://console-api.akash.network/v1/project-members/4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "role": "viewer"
    }
  }'
curl -X PATCH "https://console-api.akash.network/v1/project-members/4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "role": "viewer"
    }
  }'

DELETE /v1/project-members/{id}

Revoke a grant, effective from the member's next request. Owners, admins and the project's admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Grant id

Response 204 No Content

curl -X DELETE "https://console-api.akash.network/v1/project-members/4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X DELETE "https://console-api.akash.network/v1/project-members/4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/project-budgets

List the project budgets the caller can read, with this month's committed spend. Owners, admins, billing members and the project's admins.

Parameter Description
x-api-key header string required
Your API key
projectId query string (uuid)
Only the budget of this project

Response 200 OK

Field Description
data[].id string (uuid)
Budget id
data[].projectId string (uuid)
Project id
data[].monthlyAmountUsd number
Deposits allowed per calendar month (UTC), in USD
data[].alertThresholdPercent number
Share of the budget at which owners and admins are emailed, once a month
data[].stopTopUps boolean
Whether top-ups of running deployments also stop at the budget
data[].currentPeriod.committedUsd number
Deposits recorded this month, the figure new deposits are judged against
curl "https://console-api.akash.network/v1/project-budgets?projectId=7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/project-budgets?projectId=7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v1/project-budgets

Set a monthly budget for a project. New deployments that would pass it are refused with project_budget_exceeded; top-ups are refused too when stopTopUps is on. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
data.projectId body string (uuid) required
Project id
data.monthlyAmountUsd body number required
From 1 to 10000000, in whole cents
data.alertThresholdPercent body integer
From 1 to 100. Default 80
data.stopTopUps body boolean
Also refuse top-ups of the project's running deployments past the budget. Default false

Response 201 Created

409 with code project_budget_exists when the project already has a budget. Change it with PATCH instead.
curl -X POST "https://console-api.akash.network/v1/project-budgets" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b",
      "monthlyAmountUsd": 500,
      "alertThresholdPercent": 80,
      "stopTopUps": false
    }
  }'
curl -X POST "https://console-api.akash.network/v1/project-budgets" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b",
      "monthlyAmountUsd": 500,
      "alertThresholdPercent": 80,
      "stopTopUps": false
    }
  }'

PATCH /v1/project-budgets/{id}

Change a project's monthly budget. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Budget id
data.monthlyAmountUsd body number
New monthly amount
data.alertThresholdPercent body integer
New alert threshold
data.stopTopUps body boolean
Whether top-ups also stop at the budget

Response 200 OK

curl -X PATCH "https://console-api.akash.network/v1/project-budgets/8a9b0c1d-2e3f-4a5b-b6c7-d8e9f0a1b2c3" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "monthlyAmountUsd": 750
    }
  }'
curl -X PATCH "https://console-api.akash.network/v1/project-budgets/8a9b0c1d-2e3f-4a5b-b6c7-d8e9f0a1b2c3" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "monthlyAmountUsd": 750
    }
  }'

DELETE /v1/project-budgets/{id}

Remove a project's monthly budget. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
id path string (uuid) required
Budget id

Response 204 No Content

curl -X DELETE "https://console-api.akash.network/v1/project-budgets/8a9b0c1d-2e3f-4a5b-b6c7-d8e9f0a1b2c3" \
  -H "x-api-key: $AKASH_API_KEY"
curl -X DELETE "https://console-api.akash.network/v1/project-budgets/8a9b0c1d-2e3f-4a5b-b6c7-d8e9f0a1b2c3" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/project-spend

Report the active organization's spend per project over a date range. Callers see the projects they can reach; the organization total is for owners, admins and billing members.

Parameter Description
x-api-key header string required
Your API key
startDate query string
First UTC day (YYYY-MM-DD), inclusive. Defaults to the first day of endDate's month
endDate query string
Last UTC day, inclusive. Defaults to today. The range spans at most 366 days

Response 200 OK

Field Description
data.projects[] array
projectId, name, isDefault, isDeleted and the amounts below, per project
data.projects[].committedUsd number
Deposits signed for the project's deployments in the range
data.projects[].consumedUsd number
What their leases cost over the range, including estimatedConsumedUsd
data.projects[].estimatedConsumedUsd number
Part of consumedUsd accrued since the last on-chain settlement
data.unassigned object | null
Spend of deployments filed in no project. Null for a caller limited to some projects
data.total object | null
The organization's whole spend. Null for a caller limited to some projects
data.isEstimated boolean
Whether any figure includes an estimate
curl "https://console-api.akash.network/v1/project-spend?startDate=2026-10-01&endDate=2026-10-31" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/project-spend?startDate=2026-10-01&endDate=2026-10-31" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/deployment-spend

Report what the active organization's deployments consumed over a date range, per deployment and per project and day. Takes the same startDate and endDate as GET /v1/project-spend.

Parameter Description
x-api-key header string required
Your API key
startDate query string
First UTC day (YYYY-MM-DD), inclusive
endDate query string
Last UTC day, inclusive

Response 200 OK

Field Description
data.projects[] array
The projects the caller can see, and deleted ones with spend in the range
data.days[] array
date, projectId and consumedUsd per project and UTC day, leaving out days with no spend
data.deployments[] array
dseq, name, projectId, consumedUsd, hours, gpuHours and gpuModels per deployment, most spent first
curl "https://console-api.akash.network/v1/deployment-spend?startDate=2026-10-01&endDate=2026-10-31" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/deployment-spend?startDate=2026-10-01&endDate=2026-10-31" \
  -H "x-api-key: $AKASH_API_KEY"

GET /v1/organization-activities

List what happened in the active organization, newest first, within the projects the caller can reach. A key that is not bound to a project also sees organization-wide events, such as members joining.

Parameter Description
x-api-key header string required
Your API key
projectId query string (uuid)
Only the activities of this project
limit query integer
Activities per page, at most 100. Default 20
cursor query string
nextCursor of the previous page

Response 200 OK

Field Description
data[].type string
organization_created, organization_renamed, project_created, member_invited, member_joined, member_updated, member_granted, member_revoked, deployment_created, deployment_closed or deployment_moved
data[].projectId string | null
Project the activity happened in, null for an organization-wide one
data[].actor object | null
{ id, username } of who did it, null for the system or a deleted user
data[].payload object
Values for the activity text, per type, such as dseq and name
nextCursor string | null
Pass it as cursor for the next page. Null on the last page
curl "https://console-api.akash.network/v1/organization-activities?projectId=7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b&limit=20" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/organization-activities?projectId=7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b&limit=20" \
  -H "x-api-key: $AKASH_API_KEY"

PATCH /v1/deployments/{dseq}/project

Move a deployment to another project of the active organization. It keeps running; only the project it is filed in changes. Owners and admins.

Parameter Description
x-api-key header string required
Your API key
dseq path string required
Deployment sequence ID
data.projectId body string (uuid) required
Target project

Response 200 OK

Field Description
data.dseq string
Deployment sequence ID
data.projectId string (uuid)
Project the deployment is now filed in
Other roles get 403. An unknown deployment or project answers 404.
curl -X PATCH "https://console-api.akash.network/v1/deployments/1234567/project" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b"
    }
  }'
curl -X PATCH "https://console-api.akash.network/v1/deployments/1234567/project" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b"
    }
  }'

GET /v1/deployment-locations/{dseq}

Find the organization and project a deployment is filed in. With an API key, it only looks within the key's organization and reach.

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

Response 200 OK

Field Description
data.organizationId string (uuid)
Organization id
data.organizationSlug string
Organization slug
data.projectId string | null
Project id, null when the deployment is filed in no project
curl "https://console-api.akash.network/v1/deployment-locations/1234567" \
  -H "x-api-key: $AKASH_API_KEY"
curl "https://console-api.akash.network/v1/deployment-locations/1234567" \
  -H "x-api-key: $AKASH_API_KEY"

POST /v1/api-keys

Create an API key in the active organization, optionally limited to one of its projects. A project-bound key cannot manage members, invitations, projects, billing or API keys.

Parameter Description
x-api-key header string required
Your API key
data.name body string required
Key name
data.expiresAt body string
ISO 8601 date-time, in the future and at most one year from now. Defaults to one year after creation. A later date: 400
data.projectId body string (uuid)
Limits the key to this project of the organization. Unknown or out of reach: 404

Response 201 Created

Field Description
data.apiKey string
The secret, returned only here
data.organizationId string (uuid)
Organization the key acts in
data.projectId string | null
Only project the key reaches, or null for every project its owner can reach
GET /v1/api-keys lists your keys with the same organizationId and projectId fields, without the secret.
curl -X POST "https://console-api.akash.network/v1/api-keys" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "checkout-api CI",
      "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b"
    }
  }'
curl -X POST "https://console-api.akash.network/v1/api-keys" \
  -H "x-api-key: $AKASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "checkout-api CI",
      "projectId": "7d2e4a61-3b9c-4f0e-a5d8-6c1b2e3f4a5b"
    }
  }'

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