SDK reference

Quickstart

Add your first workflow run around the business logic you already have.

Before you start

You need a running Flowmark API, a project server-write key, and the SDK. The published @flowmarkdev/node README is the implementation contract for adding markers in an existing app.

npm i @flowmarkdev/node

That pulls @flowmarkdev/core automatically. Password reset is not available yet. For local services, read local development.

1. Configure the server

Set these in your server environment, not in browser-visible variables:

FLOWMARK_API_KEY=<your-project-server-write-key>
FLOWMARK_API_URL=https://api.flowmark.dev

The URL is the API origin, not /v1/events. Use your own deployment address when self-hosting. Production requires an explicit URL. See configuration for defaults and overrides.

2. Create one shared client

// lib/flowmark.ts (server only)
import { createFlowmark } from "@flowmarkdev/node"

export const flowmark = createFlowmark()

Using Next.js? Import from @flowmarkdev/node/next instead and follow the Next.js guide for automatic request-lifecycle delivery.

3. Add markers to an existing function

loadInvoices, saveValidInvoices, and logger below are your application's existing helpers, not SDK APIs. No business work moves into Flowmark.

import { flowmark } from "./lib/flowmark"

async function importInvoices(batchId: string) {
  const run = flowmark.workflow("invoice.import", {
    properties: { batchId },
  })
  try {
    const invoices = await loadInvoices(batchId)
    run.step("source-loaded", { properties: { count: invoices.length } })
    const result = await saveValidInvoices(invoices)
    run.done({ result: { imported: result.imported, skipped: result.skipped } })
    return result
  } catch (error) {
    run.fail({ code: "IMPORT_FAILED" })
    logger.error({ batchId, error }, "Import failed")
    throw error
  }
}

Four markers: start, checkpoint, completion, failure. workflow() starts an independent run; step() records a milestone; done() attaches a bounded business summary; fail() reports failure without throwing. Your function keeps ownership of its return value and original exception.

4. Drain delivery at a process boundary

Markers queue delivery automatically. In a plain Node.js script or worker, drain the client before the process exits:

try {
  await flowmark.shutdown()
} catch (error) {
  console.error("Flowmark delivery failed", error)
}

Do this once at the job/process boundary, not inside every shared function. For a long-running process, use flush() without closing the client. An explicit drain can reject; handle that separately from the business result. The Next.js adapter handles draining after the response.

5. Inspect the run

Open your dashboard connected to the same project. Find invoice.import, then open the run. You should see the source checkpoint, a completed or failed outcome, and a result summary on successful completion.

If it is missing, follow troubleshooting. A missing terminal event is not proof the business operation failed.

Where to go next

On this page