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

# JavaScript and TypeScript

> Create, call, inspect, reset, renew, and destroy sandboxes with the Archal client.

## Install and create a client

```bash theme={null}
npm install archal@0.11.0
```

```ts theme={null}
import { ArchalEnvironmentClient } from 'archal';

const archal = new ArchalEnvironmentClient({
  apiKey: process.env.ARCHAL_API_KEY!,
});
```

The API key controls sandbox lifecycle. Keep it out of the process being tested.

## Create from explicit state

```ts theme={null}
const sandbox = await archal.createSession(
  {
    environments: ['github'],
    ttlSeconds: 1800,
    initialState: {
      github: {
        format: 'json',
        value: githubState,
      },
    },
  },
  { idempotencyKey: `github-${process.env.CI_RUN_ID}` },
);
```

`createSession` waits until every environment is ready. If readiness fails, it
attempts to destroy the new sandbox before returning the original error. Use
`startSession` when you need the sandbox ID immediately, then call
`waitUntilReady`.

## Call a provider-shaped endpoint

```ts theme={null}
try {
  const response = await archal.callEnvironment(sandbox.sessionId, 'github', {
    method: 'POST',
    path: '/user/repos',
    body: { name: 'checkout-test', private: true },
  });

  console.log(response.status, response.data);
} finally {
  await archal.destroySession(sandbox.sessionId);
}
```

`callEnvironment` reads the connection from the sandbox, removes any caller
provider authorization, and applies the returned scoped credential headers.
It rejects paths that leave the environment base URL.

## State

```ts theme={null}
const before = await archal.getState(sandbox.sessionId, 'github');

const diff = await archal.diffState(sandbox.sessionId, 'github', {
  source: 'explicit',
  before: before.state,
});

await archal.resetEnvironment(sandbox.sessionId, 'github');
```

A diff always requires the explicit prior JSON state. It does not infer the
reset baseline.

## Longer work

`renewSession` refreshes expiry and scoped connections. `manageSessionLease`
can renew before the nearest lease boundary and refresh credentials. Stopping a
managed lease stops its renewal timer, but does not destroy the sandbox. Read
the returned `hardExpiresAt` instead of assuming one plan-wide maximum.

## Common client methods

* `listEnvironments` and `describeEnvironment`
* `listSessions`, `startSession`, `createSession`, and `getSession`
* `waitUntilReady`, its `awaitSessionReady` alias, and `waitUntilDestroyed`
* `validateState`, `getState`, `loadState`, and `diffState`
* `callEnvironment` and `getEvidence`
* `resetEnvironment`, `resetSession`, and `renewSession`
* `manageSessionLease` and `destroySession`
