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

# Quickstart

> Install @endstate-sdk/core and make your first call, with typed operations, typed errors, and retries derived from the spec.

`@endstate-sdk/core` is the Endstate API in TypeScript. One build runs in
Node 20+, edge runtimes, and the browser, with **zero runtime dependencies**
and an Apache-2.0 license.

Field names are the API's own. What you read in the
[API reference](/api-reference/introduction) is what you get in TypeScript:
`chip_id`, `external_id`, `session_token`, `has_more`, `next_cursor`. Nothing
is renamed, so you can move between the SDK and raw HTTP without translating.

## Install

<CodeGroup>
  ```bash npm theme={null}
  npm install @endstate-sdk/core
  ```

  ```bash bun theme={null}
  bun add @endstate-sdk/core
  ```

  ```bash pnpm theme={null}
  pnpm add @endstate-sdk/core
  ```
</CodeGroup>

The package is ESM-only. `VERSION` exports the installed version, and the SDK
sends it on the `User-Agent` outside the browser, so support can tell which
version made a call.

## Your first call

```ts theme={null}
import { EndstateClient, secretKey } from "@endstate-sdk/core";

const endstate = new EndstateClient({
  apiKey: secretKey(process.env.ENDSTATE_API_KEY),
});

const unit = await endstate.units.create({
  collection_id: "8e1a7f50-90ab-4cde-8012-3456789abcde",
  external_id: "jacket-0001",
  name: "Field Jacket",
});
```

`apiKey` is typed `` `end_sk_${string}` ``, so a key read from the environment
needs narrowing. `secretKey()` does it and throws a named
`EndstateConfigError` at startup, rather than letting a missing or
wrong-prefixed key surface as a `401` on your first call.

## Pick your client

Which one you use is decided by **where the code runs**, not by what it does.

<CardGroup cols={2}>
  <Card title="Server" icon="server" href="/sdks/core/server">
    `EndstateClient` with a secret key (`end_sk_...`). Every operation in the
    spec, the `waitUntil` helpers, pagination, and the typed escape hatch.
  </Card>

  <Card title="Browser" icon="globe" href="/sdks/core/browser">
    `EndstatePublicClient` with a publishable key (`end_pk_...`). Records taps;
    everything further is authorized by the tap itself.
  </Card>
</CardGroup>

<Warning>
  A secret key grants full access to your organization. It belongs on your
  server and nowhere else - never in browser or Electron-renderer code, and
  never behind a public proxy endpoint.
</Warning>

## Then

<CardGroup cols={2}>
  <Card title="Tap sessions" icon="nfc" href="/sdks/core/tap-sessions">
    Turn a tap into a session that can claim, transfer, and read a unit.
  </Card>

  <Card title="Errors and retries" icon="triangle-alert" href="/sdks/core/errors-and-retries">
    Typed errors, which calls retry, and how idempotency keys are chosen.
  </Card>
</CardGroup>
