Programmatic management of Deno Deploy Apps[src]

Beyond provisioning microVMs, the SDK provides APIs for creating and managing Deploy apps inside your organization. Automating these workflows can help when you need to:

  • spin up isolated apps for previews or QA

  • keep multiple environments in sync

  • integrate Deploy provisioning directly into your CI/CD

  • clean up stale or unused apps on a schedule

The SDK wraps the Deno Deploy REST API.

Getting started

Authentication

You will need a Deno Deploy API token with appropriate permissions to manage apps. You can find your token in the Deno Deploy console under Sandboxes > Integrate into your app.

Click the + Create Token button to generate a new token if you don't have one yet.

Pass the DENO_DEPLOY_TOKEN environment variable, scoped to your organization, when instantiating the client or creating a sandbox to manage apps. The Client class exposes create, list, retrieve, update, and delete methods for every app that belongs to the organization the token is scoped to.

Initialize the client

JavaScript
import { Client } from "@deno/sandbox";

const client = new Client();
Python
from deno_sandbox import DenoDeploy

sdk = DenoDeploy()
Python (Async)
from deno_sandbox import AsyncDenoDeploy

sdk = AsyncDenoDeploy()

The SDK uses the same DENO_DEPLOY_TOKEN environment variable for authentication. Provide tokens scoped to the organization you want to manage.

Create an app

JavaScript
const app = await client.apps.create({
  slug: "my-app-from-sdk",
});

console.log(app);
// {
//   id: "4416a358-4a5f-45b2-99b5-3ebcb4b63b5f",
//   slug: "my-app-from-sdk",
//   updated_at: "2025-11-25T05:29:08.777Z",
//   created_at: "2025-11-25T05:29:08.777Z"
// }
Python
app = sdk.apps.create(slug="my-app-from-sdk")

print(app)
# {
#   "id": "4416a358-4a5f-45b2-99b5-3ebcb4b63b5f",
#   "slug": "my-app-from-sdk",
#   "updated_at": "2025-11-25T05:29:08.777Z",
#   "created_at": "2025-11-25T05:29:08.777Z"
# }
Python (Async)
app = await sdk.apps.create(slug="my-app-from-sdk")

print(app)
# {
#   "id": "4416a358-4a5f-45b2-99b5-3ebcb4b63b5f",
#   "slug": "my-app-from-sdk",
#   "updated_at": "2025-11-25T05:29:08.777Z",
#   "created_at": "2025-11-25T05:29:08.777Z"
# }

The slug is required and must be unique inside the organization. You will also be able to provide optional metadata such as name and description as the API evolves.

List apps

JavaScript
const list = await client.apps.list();
console.log(list.items); // first page (30 newest apps)

for await (const app of list) {
  console.log(app.slug); // paginated iterator
}
Python
page = sdk.apps.list()
print(page.items)  # first page (30 newest apps)

for item in page.items:
  print(item["slug"])
Python (Async)
page = await sdk.apps.list()
print(page.items)  # first page (30 newest apps)

async for item in page:
  print(item["slug"])  # paginated iterator

Use iteration to walk every app in the organization without managing cursors yourself.

Retrieve an app

JavaScript
const appBySlug = await client.apps.get("my-app-from-sdk");
const appById = await client.apps.get("bec265c1-ed8e-4a7e-ad24-e2465b93be88");
Python
app_by_slug = sdk.apps.get("my-app-from-sdk")
app_by_id = sdk.apps.get("bec265c1-ed8e-4a7e-ad24-e2465b93be88")
Python (Async)
app_by_slug = await sdk.apps.get("my-app-from-sdk")
app_by_id = await sdk.apps.get("bec265c1-ed8e-4a7e-ad24-e2465b93be88")

Fetching supports either the slug or the UUID, making it easy to use whichever identifier you have on hand.

Update app metadata

JavaScript
const updated = await client.apps.update(
  "bec265c1-ed8e-4a7e-ad24-e2465b93be88",
  { slug: "my-cool-app" },
);
console.log(updated.slug); // "my-cool-app"
Python
updated = sdk.apps.update(
  "bec265c1-ed8e-4a7e-ad24-e2465b93be88",
  slug="my-cool-app"
)
print(updated["slug"])  # "my-cool-app"
Python (Async)
updated = await sdk.apps.update(
  "bec265c1-ed8e-4a7e-ad24-e2465b93be88",
  slug="my-cool-app"
)
print(updated["slug"])  # "my-cool-app"

This is handy when a team renames a service or you want to enforce consistent slug patterns across organizations.

Delete an app

JavaScript
await client.apps.delete("legacy-chaotic-app");
await client.apps.delete("bec265c1-ed8e-4a7e-ad24-e2465b93be88");
Python
sdk.apps.delete("legacy-chaotic-app")
sdk.apps.delete("bec265c1-ed8e-4a7e-ad24-e2465b93be88")
Python (Async)
await sdk.apps.delete("legacy-chaotic-app")
await sdk.apps.delete("bec265c1-ed8e-4a7e-ad24-e2465b93be88")

Deleting accepts either identifier. Once removed, associated builds and routes are cleaned up automatically.

Publish to a Deploy app from a sandbox

The sandbox.deno.deploy() method can be used to publish resources from a sandbox to an existing Deno Deploy app. This allows you to use a sandbox as a deployment pipeline for an application hosted on Deno Deploy.

JavaScript
await using sandbox = await Sandbox.create();

// ... build your application ...

const app = await sandbox.deno.deploy("my-app", {
  options: {
    path: "build-output", // optional: path to the directory containing the application to deploy
    production: true, // optional: deploy to production
    build: {
      entrypoint: "server.ts", // optional: entrypoint to deploy
    },
  },
});

console.log(`Deployed to ${app.slug}`);
Python
sdk = DenoDeploy()

with sdk.sandbox.create() as sandbox:
  # ... build your application ...

  build = sandbox.deno.deploy(
    "my-app",
    path="build-output",  # optional: path to the directory containing the application to deploy
    production=True,  # optional: deploy to production
    entrypoint="server.ts",  # optional: entrypoint to deploy
  )

  print(f"Deployed revision ID: {build.id}")
Python (Async)
sdk = AsyncDenoDeploy()

async with sdk.sandbox.create() as sandbox:
  # ... build your application ...

  build = await sandbox.deno.deploy(
    "my-app",
    path="build-output",  # optional: path to the directory containing the application to deploy
    production=True,  # optional: deploy to production
    entrypoint="server.ts",  # optional: entrypoint to deploy
  )

  print(f"Deployed revision ID: {build.id}")
Last updated 2026-03-19 denoland/docs#9e5dd8d