Skip to main content
This guide walks you through instrumenting a backend function with Failpath from scratch. You will initialize the CLI, inspect the generated flow definition, install the SDK, create a client, wrap your business steps, and publish your flow so events appear on your dashboard.
1

Initialize your project

Run the following command in the root of your backend repository, replacing fp_project_xxx with your actual project key:
The init command does five things:
  • Writes FAILPATH_PROJECT_KEY to a .env file
  • Adds .env to your .gitignore
  • Creates .failpath/AGENTS.md
  • Pulls your project’s current dashboard graph into .failpath/flows.json
  • Generates .failpath/sdk.ts for typed flow and step keys
2

Inspect the generated flow keys

Open .failpath/flows.json. You will see one or more flow objects. Two fields are important when writing SDK code:
  • flow.slug — pass this string as the first argument to run(). It identifies which flow a run belongs to.
  • node.sdkStepKey — pass this string as the first argument to step(). It maps a recorded event to a specific node on your dashboard graph.
The CLI also generates .failpath/sdk.ts from this graph. Import failpathFlows from that file when you instrument code so the slugs and step keys autocomplete.
3

Install @failpath/sdk

Add the SDK to your project:
4

Create the client

Create the Failpath client once at the module level and export it as a singleton. Importing the same instance across your codebase ensures that configuration — like defaultMetadata — is applied consistently everywhere.
The projectKey is read from the environment variable written by npx failpath init. In local development your .env file supplies it automatically.
5

Wrap your function steps

Import your client and failpathFlows, then use run() to start a run and wrap each business step with step(). Reuse the same runId for every step that belongs to the same request.
Each step() call queues a running event before the wrapped operation executes, then queues success or error when it finishes. Sends run in the background by default, so call flush() before a short-lived request, job, or script exits unless your runtime keeps background work alive with waitUntil.
Wrap business steps like validateCart, chargeCard, and sendReceiptEmail — not tiny helpers, utility functions, or repository calls. Each wrapped step should represent a meaningful unit of work you want to track on your dashboard.
6

Publish and view your dashboard

Push your local flow definition to Failpath:
Then trigger your function — call the endpoint, run the job, or fire the webhook — and open your Failpath dashboard. You will see the run appear with success or error status on each step node.