DocsAPI keys

API keys

This page shows you where to create an API key, how the SDKs find it, how to pass it per call, and how to rotate it. An API key authenticates every call your team makes to the Impello API. Calls to a sandbox itself carry a sandbox-scoped access token that the SDK attaches for you (see Network and Filesystem).

Where to find your key

Keys are created and read at dashboard.impello.ai/keys. That page is the only place a key is ever shown.

  • A key belongs to the team, not to the person who made it. Every member of the team can see and manage the team's keys.
  • A team can hold several keys. Give each one a name of up to 64 characters, and rename it later if you want.
  • The full key is shown once, when it is created. Impello stores a hash of it, so a key you did not copy cannot be recovered, only replaced.
  • The keys page lists every key the team created, with its name, a masked value, when it was created, when it was last used and when it expires. The reserved dashboard-session key that keeps your browser signed in is hidden, and cannot be renamed or deleted there.
  • A key can expire. When you create it, choose No expiration (the default), 7, 30 or 90 days, 1 year, or a custom date from tomorrow on. The key works through the end of that day, in your local time. The expiry cannot be changed later, and an expired key shows an Expired badge on the keys page.

Set it once

Export the key as IMPELLO_API_KEY and both SDKs pick it up. Nothing else on this page is required.

export IMPELLO_API_KEY=imp_...

With the variable set, no call needs a key argument.

import { Sandbox } from '@impello/sdk'

const sandbox = await Sandbox.create('base')
const result = await sandbox.commands.run('echo hello')
console.log(result.stdout)

await sandbox.kill()

Over HTTP the key travels in the X-API-Key header. The base URL is https://api.sandbox.impello.ai.

Pass it per call

Every call that reaches the API also accepts the key as an option. A key passed this way wins over the environment variable. The example creates a sandbox with one key and lists sandboxes with another.

import { Sandbox } from '@impello/sdk'

const sandbox = await Sandbox.create('base', {
  apiKey: process.env.TEAM_A_KEY,
})

const paginator = Sandbox.list({ apiKey: process.env.TEAM_B_KEY })
const sandboxes = await paginator.nextItems()

await sandbox.kill()

You can also bind the key to a client once and use client.Sandbox (and client.AsyncSandbox in Python) in place of the top-level classes. A parameter passed to a single call beats the client, and the client beats the environment. The TypeScript client needs @impello/sdk 0.3.2 or later.

import { Impello } from '@impello/sdk'

const client = new Impello({ apiKey: process.env.TEAM_A_KEY })
const sandbox = await client.Sandbox.create('base')

await sandbox.kill()

What a key can do

A key acts for the whole team. It can create, connect to, list, pause, resume and kill the team's sandboxes, read their logs and metrics, change their network rules, and build, list and delete the team's templates. It cannot read, create, rename or delete API keys; the API refuses that route to a team key, and those operations live in the dashboard, behind your login.

Revoke and rotate

Delete a key on the keys page to revoke it. The deletion cannot be undone, and anything still using that key is refused.

To rotate a key without downtime:

  1. Create a new key on the keys page.
  2. Set IMPELLO_API_KEY to the new value everywhere the old one is used, and redeploy.
  3. Delete the old key. Its "last used" column tells you whether anything is still on it.

Key format

A key is imp_ followed by hexadecimal characters. Both SDKs check the shape before sending a request, and the two checks are not the same. The Python SDK requires imp_ plus hex and raises AuthenticationException on anything else. The TypeScript SDK is looser: it also accepts the older prefix, and raises AuthenticationError only when the key is not shaped like a key at all. Neither check decides whether the key is a valid one; that is the API's answer.

A missing key raises the same error type, with a message pointing at the API Keys tab on the dashboard. From @impello/sdk 0.3.2 the TypeScript message names IMPELLO_API_KEY and shows an imp_ example key; earlier versions name the older environment variable and show an old-prefix example key — set IMPELLO_API_KEY to an imp_ key either way. A key the API rejects comes back as HTTP 401, which the SDKs raise as AuthenticationError or AuthenticationException with the message Unauthorized, please check your credentials. — Python prefixes it with 401: . See Errors.

The TypeScript SDK can skip the shape check: pass validateApiKey: false or set IMPELLO_VALIDATE_API_KEY=false. The Python SDK always checks; its validate_api_key parameter is deprecated and has no effect.

A key minted before Impello moved to its own prefix cannot be made to work by any client, and the two SDKs say so at different moments. Python refuses it locally, raising AuthenticationException with a message naming the 2026-08-30 cutover. TypeScript lets it through the shape check, so the request goes out and comes back as HTTP 401. Replace the key on the keys page; see Migrate.

Other settings

Each setting is read from the environment under its IMPELLO_ name. The older prefix is still read as a fallback, so an existing environment keeps working — see Migrate.

VariableDefaultWhat it does
IMPELLO_API_KEYnoneThe key. Starts with imp_
IMPELLO_DOMAINsandbox.impello.aiThe domain the API and the sandboxes sit on
IMPELLO_API_URLhttps://api. plus the domainThe API address
IMPELLO_VALIDATE_API_KEYtrueSet to false to skip the key shape check. TypeScript only
IMPELLO_DEBUGfalseTalk to a local API at http://localhost:3000 and reach sandboxes on localhost, for running the SDK against a local stack

Most of these settings, and a few that have no environment variable, can be passed on any call that reaches the API: Sandbox.create, Sandbox.connect, Sandbox.list, Sandbox.kill and the rest. Where a TypeScript option is narrower than that, the table says so.

TypeScriptPythonDefaultWhat it does
apiKeyapi_keyIMPELLO_API_KEYThe key
domaindomainIMPELLO_DOMAINThe domain
apiUrlapi_urlIMPELLO_API_URLThe API address
requestTimeoutMsrequest_timeout60000 ms / 60.0 sHow long one API request may take
apiHeadersapi_headersnoneExtra headers sent with every API request
proxyproxynoneProxy for every request, including those to the sandbox. In TypeScript the Sandbox class accepts it on Sandbox.create and Sandbox.connect only, and it carries to the sandbox from there; every Template method accepts it too. From @impello/sdk 0.3.2 Template.build sends its file uploads through it as well; 0.3.1 and earlier upload them without it. TypeScript needs Node.js with the undici package. From @impello/sdk 0.3.2, on Bun, Deno, edge runtimes or in the browser, or when undici cannot be loaded, requests fail with InvalidArgumentError and are never sent without the proxy; 0.3.1 and earlier send them without it. Python accepts it on every call
validateApiKeyvalidate_api_keytrueSet to false to skip the key shape check in TypeScript. The Python parameter is deprecated and has no effect
signal—noneAn AbortSignal that cancels the request. TypeScript only, and not accepted by Sandbox.list — pass it to paginator.nextItems({ signal }) instead

requestTimeoutMs is milliseconds in TypeScript and request_timeout is seconds in Python; 0 disables the request timeout in both. Neither bounds the sandbox's own lifetime — that is timeoutMs or timeout on create, covered in Timeouts.

Logging is a separate option rather than a variable. Pass logger to Sandbox.create or Sandbox.connect, and the sandbox keeps using it for every later request. In TypeScript it accepts anything shaped like console; in Python it is a standard library logging.Logger. Without one, neither SDK logs requests.

The TypeScript SDK also reads IMPELLO_ACCESS_TOKEN into a deprecated accessToken option, and sends it as a bearer token. An API key is the only credential you need; leave it unset. The Python SDK does not read it at all.

Next: Templates.