> ## Documentation Index
> Fetch the complete documentation index at: https://e2b-automation-sdk-reference-sync.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK client

> Create a custom client with options

The top-level `Sandbox`, `Volume`, and `Template` exports read their configuration from the environment variables (`E2B_API_KEY`, `E2B_DOMAIN`, …). If you need an explicit configuration — for example several API keys, teams, or [self-hosted deployments](/byoc) in a single process — create an `E2B` client and use the resources it exposes.

<Note>
  Per-call options take precedence over the client's options, which take precedence over the environment variables.
</Note>

<CodeGroup>
  ```js JavaScript & TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  import { E2B } from 'e2b'

  const client = new E2B({ apiKey: 'YOUR_API_KEY', domain: 'e2b.app' })

  const sandbox = await client.Sandbox.create()
  const result = await sandbox.commands.run('echo "Hello from E2B!"')
  console.log(result.stdout) // Hello from E2B!
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  from e2b import E2B

  client = E2B(api_key="YOUR_API_KEY", domain="e2b.app")

  sandbox = client.Sandbox.create()
  result = sandbox.commands.run('echo "Hello from E2B!"')
  print(result.stdout)  # Hello from E2B!
  ```

  ```python Python (async) theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  from e2b import E2B

  client = E2B(api_key="YOUR_API_KEY", domain="e2b.app")

  sandbox = await client.AsyncSandbox.create()
  result = await sandbox.commands.run('echo "Hello from E2B!"')
  print(result.stdout)  # Hello from E2B!
  ```
</CodeGroup>

The classes exposed by the client behave exactly like the top-level exports of the same name — only the defaults change. You can also destructure them and use them as usual.

<CodeGroup>
  ```js JavaScript & TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  const { Sandbox, Volume, Template } = new E2B({ apiKey: 'YOUR_API_KEY' })

  const sandbox = await Sandbox.create()
  const volume = await Volume.create('my-volume')
  const exists = await Template.exists('my-template')
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  client = E2B(api_key="YOUR_API_KEY")
  Sandbox, Volume, Template = (
      client.Sandbox,
      client.Volume,
      client.Template,
  )

  sandbox = Sandbox.create()
  volume = Volume.create("my-volume")
  exists = Template.exists("my-template")
  ```

  ```python Python (async) theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  client = E2B(api_key="YOUR_API_KEY")
  Sandbox, Volume, Template = (
      client.AsyncSandbox,
      client.AsyncVolume,
      client.AsyncTemplate,
  )

  sandbox = await Sandbox.create()
  volume = await Volume.create("my-volume")
  exists = await Template.exists("my-template")
  ```
</CodeGroup>

## Client options

The client accepts the same options as the individual SDK calls, for example `apiKey`/`api_key`, `domain`, `requestTimeoutMs`/`request_timeout`, `proxy`, `apiHeaders`/`api_headers`, and `logger`.

In JavaScript, the only exception is `signal`: it cancels a single in-flight request, so it can only be passed per call.

## Multiple clients

Clients are isolated from each other and from the env-configured top-level exports, so you can use as many of them side by side as you need.

<CodeGroup>
  ```js JavaScript & TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  import { E2B, Sandbox } from 'e2b'

  const production = new E2B({ apiKey: 'PRODUCTION_API_KEY' })
  const staging = new E2B({ apiKey: 'STAGING_API_KEY', domain: 'e2b-staging.dev' })

  await production.Sandbox.create()
  await staging.Sandbox.create()

  // Still uses the E2B_API_KEY environment variable.
  await Sandbox.create()
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  from e2b import E2B, Sandbox

  production = E2B(api_key="PRODUCTION_API_KEY")
  staging = E2B(api_key="STAGING_API_KEY", domain="e2b-staging.dev")

  production.Sandbox.create()
  staging.Sandbox.create()

  # Still uses the E2B_API_KEY environment variable.
  Sandbox.create()
  ```

  ```python Python (async) theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  from e2b import E2B, AsyncSandbox

  production = E2B(api_key="PRODUCTION_API_KEY")
  staging = E2B(api_key="STAGING_API_KEY", domain="e2b-staging.dev")

  await production.AsyncSandbox.create()
  await staging.AsyncSandbox.create()

  # Still uses the E2B_API_KEY environment variable.
  await AsyncSandbox.create()
  ```
</CodeGroup>

## Multiple regions

<Note>
  Regions do not share state. A project and its API key belong to exactly one region, and the sandboxes, templates, and volumes it owns exist only there. Two things to plan for:

  * **Build your own templates once per region.** There is no way to copy a template between regions, so run [`Template.build`](/template/build) through each region's client. The same template name in every region is fine.
  * **A sandbox ID only resolves in its own region.** Connect to a sandbox, list it, or kill it through the client for the region that created it.
</Note>

If a single process only ever talks to one region, you do not need a client at all. Set `E2B_API_KEY` and `E2B_DOMAIN` to that region's values and keep using the top-level exports.

E2B's managed cloud runs in three regions: US, EU, and APAC. US is the default on every plan. EU and APAC are available on the Pro plan and above, and are enabled for your account by [support](https://console.e2b.dev/?support=true). See [EU region](/faq/eu-region) and [Egress IP ranges](/faq/egress-ip-ranges) for more on where sandboxes run.

There is no `region` option. Each region is a separate deployment with its own API endpoint, so you select one by pointing a client at that region's `domain`. When support enables a region, they give you its domain and help you create a [project](/projects) there. That project has its own API key, so a multiregion setup is one client per region, each with its own key and domain.

<CodeGroup>
  ```js JavaScript & TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  import { E2B } from 'e2b'

  // Support gives you the domain for each region it enables for you.
  const regions = {
    us: new E2B({ apiKey: 'e2b_YOUR_US_KEY' }), // Default domain: e2b.app
    eu: new E2B({ apiKey: 'e2b_YOUR_EU_KEY', domain: 'EU_REGION_DOMAIN' }),
    apac: new E2B({ apiKey: 'e2b_YOUR_APAC_KEY', domain: 'APAC_REGION_DOMAIN' }),
  }

  // Route each workload to the region it should run in.
  const client = regions[user.region] ?? regions.us

  const sandbox = await client.Sandbox.create('my-template')
  const result = await sandbox.commands.run('echo "Hello from E2B!"')
  console.log(result.stdout) // Hello from E2B!
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  from e2b import E2B

  # Support gives you the domain for each region it enables for you.
  regions = {
      "us": E2B(api_key="e2b_YOUR_US_KEY"),  # Default domain: e2b.app
      "eu": E2B(api_key="e2b_YOUR_EU_KEY", domain="EU_REGION_DOMAIN"),
      "apac": E2B(api_key="e2b_YOUR_APAC_KEY", domain="APAC_REGION_DOMAIN"),
  }

  # Route each workload to the region it should run in.
  client = regions.get(user_region, regions["us"])

  sandbox = client.Sandbox.create("my-template")
  result = sandbox.commands.run('echo "Hello from E2B!"')
  print(result.stdout)  # Hello from E2B!
  ```

  ```python Python (async) theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
  from e2b import E2B

  # Support gives you the domain for each region it enables for you.
  regions = {
      "us": E2B(api_key="e2b_YOUR_US_KEY"),  # Default domain: e2b.app
      "eu": E2B(api_key="e2b_YOUR_EU_KEY", domain="EU_REGION_DOMAIN"),
      "apac": E2B(api_key="e2b_YOUR_APAC_KEY", domain="APAC_REGION_DOMAIN"),
  }

  # Route each workload to the region it should run in.
  client = regions.get(user_region, regions["us"])

  sandbox = await client.AsyncSandbox.create("my-template")
  result = await sandbox.commands.run('echo "Hello from E2B!"')
  print(result.stdout)  # Hello from E2B!
  ```
</CodeGroup>
