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

# Upgrade to shipdit 0.4

> Migrate the TypeScript SDK from 0.3.x to 0.4.0: removed endpoint options, telemetry-only server identify(), an awaitable close(), and timestamp targeting.

## Overview

Affects the TypeScript SDK (`shipdit`) when upgrading from 0.3.x to 0.4.0. Go and the CLI are unaffected. See the [TypeScript SDK changelog](/changelog/typescript-sdk) for the full release notes.

## 1. Remove `endpoint` and `streamEndpoint`

`createClient` throws if either option is set. Delete `endpoint` when using the default shipd edge. Replace the default shipd `streamEndpoint` with `stream: true`. For a custom gateway, also move its URL to `overrides.streamEndpoint` as shown below.

```ts theme={null}
// Before
createClient<FlagDefinitions>({
  sdkKey: process.env.SHIPD_SDK_KEY!,
  endpoint: "https://edge.useshipd.com",
  streamEndpoint: "https://ws.useshipd.com",
});

// After
createClient<FlagDefinitions>({
  sdkKey: process.env.SHIPD_SDK_KEY!,
  stream: true,
});
```

For a custom gateway, preserve its URL:

```ts theme={null}
createClient<FlagDefinitions>({
  sdkKey: process.env.SHIPD_SDK_KEY!,
  stream: true,
  overrides: { streamEndpoint: process.env.SHIPD_WS_URL! },
});
```

If you didn't pass `streamEndpoint`, omit `stream`; the client keeps polling every 30 seconds. Remove `SHIPD_EDGE_URL` and `SHIPD_WS_URL` only if you used the default shipd endpoints and no other code reads them. Keep `SHIPD_WS_URL` when using it for a custom gateway.

> [!WARNING]
>
> `overrides.unsafeEndpoint` exists for shipd development and test environments. Don't set it in
> production: the URL you pass receives your SDK key.

## 2. Pass context instead of calling `identify()` on servers

On the server client (`shipdit`), `identify()` now only records an event. Code that relied on it to set the user for later checks must pass context on each call:

```ts theme={null}
// Before
shipd.identify({ userId: user.id, traits: { plan: user.plan } });
shipd.isEnabled("new-checkout");

// After
const context = { userId: user.id, attributes: { plan: user.plan } };
shipd.isEnabled("new-checkout", context);
```

For a fixed identity, such as a single-user script, pass it once with `createClient({ context })`. Server `reset()` is a no-op and preserves the shared anonymous id. Browser clients (`shipdit/client`) still set the identity with `identify()` until `reset()`.

## 3. Optionally await `close()`

`close()` now returns a promise that resolves after pending events are delivered, delivery fails, or the timeout passes (5 seconds by default). Existing calls keep working. Await it before exiting to give pending events time to flush:

```ts theme={null}
process.on("SIGTERM", async () => {
  // Keep recording while active requests drain; bound long-lived requests.
  await new Promise<void>((resolve) => {
    const deadline = setTimeout(() => {
      server.closeAllConnections();
      resolve();
    }, 5_000);
    server.close(() => {
      clearTimeout(deadline);
      resolve();
    });
  });
  await shipd.close();
});
```

## 4. Check timestamp rules before upgrading

Ordered comparisons (`gt`, `gte`, `lt`, `lte`) now accept `YYYY-MM-DD` (midnight UTC), or a date-time with a required `Z` or `±hh:mm` zone. Zone-less date-times, lenient formats, and impossible dates compare as strings. Audit flag rules, audience conditions, and the attributes your application sends:

```ts theme={null}
// Before: implicit local timezone
const cutoff = "2026-01-02T10:00:00";

// After: choose the timezone the rule intended
const cutoff = "2026-01-02T10:00:00Z"; // UTC
// Or "2026-01-02T10:00:00-08:00" for a fixed UTC-08:00 offset
```

Don't append `Z` unless the original value meant UTC. Correct impossible dates such as `2026-02-30`, and send the same explicit timestamp format in evaluation attributes. See [How values compare](/flags/targeting#how-values-compare).

> [!WARNING]
>
> Dashboard preview adopts this grammar on dashboard deploy. Production evaluation changes only when
> you upgrade `shipdit` or `@shipdit/convex`; the edge does not evaluate rules. An older SDK can therefore
> disagree with preview before you upgrade. Saving a flag or audience with an invalid date-looking
> ordered value returns an API warning and shows a dashboard warning, while still allowing string rules.

## Roll out and roll back

Upgrade and deploy as one change: the new options require 0.4.0, and keeping the removed `endpoint` or `streamEndpoint` options throws on 0.4.0. To roll back, pin `shipdit@0.3.1` and restore `endpoint` (and `streamEndpoint`, if you streamed).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.