> ## Documentation Index
> Fetch the complete documentation index at: https://docs.amps.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Environments

> One Public API host serves two environments. Your sk_test_ key routes to sandbox simulations, your sk_live_ key to real OEM devices. The key prefix decides.

## Overview

Amps has two environments: **sandbox** and **live**. Sandbox simulates devices for development and CI; live controls real OEM hardware in production. Both reach the Public API at the same host, `https://api.amps.ai`. The environment is decided by the API key you send: an `sk_test_` key routes to sandbox, an `sk_live_` key routes to live. Each environment has its own key prefix and its own isolated data, so testing never touches customer data.

## Sandbox

The Sandbox environment is designed for **testing and development**. It provides realistic device simulations without requiring real OEM credentials or physical devices.

### Key features

* **Realistic device behaviour**: sandbox devices simulate real-world behaviour patterns based on UTC time
* **No real credentials required**: test authentication flows with mock credentials
* **Separate data**: sandbox data is completely isolated from live
* **No device limits**: test with unlimited devices without subscription constraints
* **Safe testing**: experiment without affecting real user devices or data

### Sandbox simulations

Sandbox devices simulate realistic behaviour patterns based on UTC time:

#### Vehicles

Vehicles follow time-of-day charging patterns:

* **Morning (6-9am UTC)**: Vehicle likely plugged in, charging or fully charged (80-95% battery)
* **Daytime (9am-5pm UTC)**: Vehicle likely unplugged, battery level decreases (95% → 71%)
* **Evening (5-9pm UTC)**: Vehicle may be plugged in for overnight charging (70% → 50%)
* **Night (9pm-6am UTC)**: Vehicle plugged in, charging overnight (50% → 82%)

#### Batteries

Batteries follow solar production and usage cycles:

* **Morning (6-9am UTC)**: Discharging for morning load (70% → 46%)
* **Midday (9am-3pm UTC)**: Charging from solar production (50% → 92%)
* **Evening (3-9pm UTC)**: Discharging for peak usage (90% → 30%)
* **Night (9pm-6am UTC)**: Idle or slow charging

#### Solar inverters

Solar inverters follow daily production patterns:

* **Night (6pm-6am UTC)**: No production (night mode)
* **Morning (6-9am UTC)**: Ramping up production
* **Midday (9am-3pm UTC)**: Peak production
* **Afternoon (3-6pm UTC)**: Declining production
* **Seasonal variation**: production varies by month (less in winter)

<Tip>
  Sandbox simulations use UTC time, so device behaviour will match realistic patterns regardless of your local timezone. For example, vehicles will charge at night UTC, and solar inverters will produce during daylight hours UTC.
</Tip>

The UTC patterns above describe an untouched sandbox device. As soon as you push a command, the simulation becomes command-responsive: the device's reported state reflects the commands you have sent, and holds until you push another. Sandbox device reads carry `metadata.source: "projection"` to mark them as simulated state rather than data fetched from real hardware. The full model and current limits sit on the [device state](/concepts/device-state#sandbox-versus-live) concept page.

### When to use sandbox

* Development and integration testing
* Prototyping new features
* Testing error handling and edge cases
* Learning the API without real devices
* CI/CD pipeline testing
* Demo environments

## Live

The Live environment connects to **real OEM devices** and customer data.

### Key features

* **Real device access**: connects to actual user devices via OEM APIs
* **Customer data**: all data is real and affects actual devices
* **Device limits**: subject to subscription plan limits
* **Real credentials**: requires valid OEM authentication
* **Production ready**: use for customer-facing applications

### When to use live

* Production applications
* Customer-facing integrations
* Real device control and monitoring
* Live user connections

<Warning>
  Always use Sandbox for development and testing. Only switch to Live when you're ready for production and have thoroughly tested your integration.
</Warning>

## URL structure

### Link UI

The Link UI uses the **same base URL** for both environments. The environment is determined by a query parameter:

**Base URL:**

```
https://auth.amps.ai/{appId}
```

**Sandbox:**

```
https://auth.amps.ai/{appId}?sandbox=true
```

**Live:**

```
https://auth.amps.ai/{appId}
```

The `sandbox` query parameter accepts `true` or `1` to enable sandbox mode. If omitted, the environment defaults to Live.

### Public API

The Public API uses the **same base URL** for both environments:

```
https://api.amps.ai
```

The environment is determined by the API key you send, not the hostname. A key prefixed `sk_test_` routes the request to sandbox; a key prefixed `sk_live_` routes it to live. The environment is stamped into the key at issuance and cannot be overridden per request.

## API keys

API keys are environment-specific. The prefix selects the environment:

* **Sandbox keys**: format `sk_test_...` route to sandbox simulations
* **Live keys**: format `sk_live_...` route to real OEM hardware

Both target the same host, `https://api.amps.ai`.

<Note>
  A sandbox key never reaches live data and a live key never reaches sandbox data. The split is enforced at the key, not the URL, so make sure you're sending the key for the environment you mean to hit.
</Note>

## Environment selection

### Link UI

When generating Link UI URLs for your users:

1. **For testing**: Append `?sandbox=true` to the URL
2. **For production**: Use the base URL without query parameters

Example:

```javascript theme={null}
// Sandbox URL
const sandboxUrl = `https://auth.amps.ai/${appId}?sandbox=true`;

// Live URL
const liveUrl = `https://auth.amps.ai/${appId}`;
```

### API requests

When making API requests, the host is always `https://api.amps.ai`. The key decides the environment:

1. **Sandbox**: send an `sk_test_` key
2. **Live**: send an `sk_live_` key

Example:

```bash theme={null}
# Sandbox request
curl -X GET "https://api.amps.ai/battery/{deviceId}" \
  -H "x-api-key: sk_test_xxxxxxxxxxxxxxxxxxxxxxxx"

# Live request
curl -X GET "https://api.amps.ai/battery/{deviceId}" \
  -H "x-api-key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"
```

## Reading the environment from a response

Every authenticated response reports the serving environment back to you under `meta.environment`. It takes one of two values:

| `meta.environment` | Meaning                                                               |
| ------------------ | --------------------------------------------------------------------- |
| `"sandbox"`        | The request was served by sandbox; the API key was an `sk_test_` key. |
| `"live"`           | The request was served by live; the API key was an `sk_live_` key.    |

On unauthenticated routes (the OpenAPI spec, for example) the field is omitted entirely, because there is no key to derive an environment from.

## Data isolation

Sandbox and Live environments maintain **complete data isolation**:

* Separate data per environment, scoped by the API key
* Separate credentials and devices
* Separate customer data
* No cross-environment data access

This ensures that your testing in Sandbox never affects production data or real user devices.

## Webhook timing

Webhook delivery timing differs between environments:

* **Sandbox**: Webhooks are delivered with a 3-minute delay after action completion (configurable)
* **Live**: Webhooks are typically delivered within 10 seconds after action completion

This delay in Sandbox allows you to test webhook handling without time pressure.

## Migration from sandbox to live

When you're ready to move from Sandbox to Live:

1. **Test thoroughly**: ensure all functionality works in Sandbox
2. **Get live API keys**: generate live API keys from your dashboard, and ensure live access is enabled on your account
3. **Swap the key**: replace your `sk_test_` key with your `sk_live_` key. The host stays `https://api.amps.ai`
4. **Update Link UI**: remove `?sandbox=true` from Link UI URLs
5. **Test with real devices**: connect real devices and verify behaviour
6. **Monitor**: watch for any differences between sandbox and live behaviour

## Next steps

<CardGroup cols={2}>
  <Card title="Getting Started" icon="rocket" href="/get-started/quickstart">
    Set up your first integration
  </Card>

  <Card title="API Authentication" icon="key" href="/get-started/authentication">
    Learn about API key authentication
  </Card>

  <Card title="Link UI Guide" icon="link" href="/guides/link-ui/getting-started">
    Understand device authentication flow
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks/receive">
    Set up webhook endpoints
  </Card>
</CardGroup>
