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

# createFailpathClient: Initializing the Failpath SDK Client

> Create a Failpath client with createFailpathClient(). Configure your project key, metadata defaults, error handling, and custom fetch options.

`createFailpathClient()` is the entry point for the Failpath SDK. Call it once with your project key and any global defaults, then export the resulting client so every part of your application shares the same instance. The client is the object from which you create runs and record steps.

## Basic usage

If your repository has `.failpath/sdk.ts`, prefer the generated typed helper:

```typescript theme={"dark"}
import { createTypedFailpathClient } from "../.failpath/sdk";

export const failpath = createTypedFailpathClient({
  projectKey: process.env.FAILPATH_PROJECT_KEY!,
});
```

This wraps `createFailpathClient()` and narrows `run()`, `step()`, `skip()`, and `recordStep()` to the flow slugs and step keys in `.failpath/flows.json`.

You can also create the base client directly:

```typescript theme={"dark"}
import { createFailpathClient } from "@failpath/sdk";

const failpath = createFailpathClient({
  projectKey: process.env.FAILPATH_PROJECT_KEY!,
});
```

<Tip>
  Create your client at module level and export it as a singleton. Importing the same instance across your codebase ensures that `defaultMetadata` and other settings are applied consistently to every event your application sends.
</Tip>

## Configuration options

<ParamField path="projectKey" type="string" required>
  Your Failpath project key, found in the Failpath dashboard. This value identifies which project receives the events you send. Use an environment variable rather than a hardcoded string to avoid committing your key to source control.
</ParamField>

<ParamField path="defaultMetadata" type="object">
  A plain object whose key/value pairs are merged into the metadata of every event the client sends. Use this for properties that apply globally — such as environment name, service name, or deployment region — so you don't have to repeat them on every run or step.

  ```typescript theme={"dark"}
  const failpath = createFailpathClient({
    projectKey: process.env.FAILPATH_PROJECT_KEY!,
    defaultMetadata: { env: "production", service: "checkout-api" },
  });
  ```
</ParamField>

<ParamField path="endpoint" type="string" default="https://api.failpath.dev">
  Overrides the API endpoint the client sends events to. This option exists for local Failpath API development only — do not set it in production deployments.
</ParamField>

<ParamField path="enabled" type="boolean" default="true">
  Set to `false` to disable all event sending. When disabled, `step()` still executes the wrapped function and returns its result normally; it simply skips the telemetry calls. Use this to silence the SDK in environments where you do not want data sent.
</ParamField>

<ParamField path="captureStack" type="boolean" default="false">
  When `true`, the SDK includes the stack trace from any error caught inside a `step()` call in the outbound error event. Disable this (the default) if your error objects contain sensitive data or if stack traces are too large to send efficiently.
</ParamField>

<ParamField path="delivery" type="&#x22;background&#x22; | &#x22;await&#x22;" default="&#x22;background&#x22;">
  Controls whether telemetry sends run in the background or block the SDK call until the send finishes. The default, `"background"`, keeps Failpath off your request latency path. Use `"await"` when you want deterministic send completion for scripts, local tools, or runtimes where background work may be stopped immediately.
</ParamField>

<ParamField path="throwOnSendError" type="boolean" default="false">
  When `true`, the SDK throws an error if a telemetry send request fails. With background delivery, call `flush()` to surface queued delivery failures. With `delivery: "await"`, the individual SDK call can throw. The default (`false`) means telemetry failures are silent — your application continues normally even if Failpath is unreachable.
</ParamField>

<ParamField path="sendTimeoutMs" type="number" default="1500">
  Maximum time, in milliseconds, that a single telemetry send can wait before the SDK aborts it. Set this to `0` to disable the timeout. Keep a finite timeout in production so a hanging network request cannot hold open a flush forever.
</ParamField>

<ParamField path="maxQueueSize" type="number" default="1000">
  Maximum number of background events that can wait in memory. When the queue is full, new events are dropped and `onError` is called if provided. This protects your process from unbounded memory growth during an extended outage.
</ParamField>

<ParamField path="waitUntil" type="(promise: Promise<void>) => void">
  Optional hook for runtimes that can keep background work alive after your handler returns. Pass your platform's `waitUntil` implementation when available.

  ```typescript theme={"dark"}
  const failpath = createFailpathClient({
    projectKey: process.env.FAILPATH_PROJECT_KEY!,
    waitUntil: (promise) => context.waitUntil(promise),
  });
  ```
</ParamField>

<ParamField path="onError" type="(err: unknown) => void">
  A callback invoked whenever a telemetry send request fails. Use this to route SDK errors into your own logging or alerting system without enabling `throwOnSendError`.

  ```typescript theme={"dark"}
  const failpath = createFailpathClient({
    projectKey: process.env.FAILPATH_PROJECT_KEY!,
    onError: (err) => logger.warn("Failpath send error", { err }),
  });
  ```
</ParamField>

<ParamField path="fetch" type="(input: RequestInfo, init?: RequestInit) => Promise<Response>">
  A custom `fetch` implementation. Supply this when your runtime does not have a native `fetch` global — for example, older versions of Node.js — or when you need to route requests through a proxy. The function signature must match the standard `fetch` API.

  ```typescript theme={"dark"}
  import fetch from "node-fetch";

  const failpath = createFailpathClient({
    projectKey: process.env.FAILPATH_PROJECT_KEY!,
    fetch,
  });
  ```
</ParamField>

## Flushing background events

The client exposes `flush()` for deterministic delivery. Use it before a short-lived process exits, at the end of a serverless request when you do not have `waitUntil`, or in tests that assert sent events.

```typescript theme={"dark"}
await failpath.flush();
```

`flush()` resolves when all queued events have either sent or failed. If `throwOnSendError` is `true`, it rejects with the first queued delivery error.

<Note>
  Use the mock client from `@failpath/sdk/testing` in automated tests when you want to assert emitted events. Use `enabled: false` only when you want instrumentation to be inert.
</Note>
