Product Updates

The Firma.dev TypeScript e-signature SDK is here: typed, zero-dependency, every endpoint covered

If you have been wiring e-signatures into your product with hand-written fetch calls, that work is now optional. The official Firma.dev TypeScript SDK is live on npm. One typed client, all 66 partner API endpoints, no runtime dependencies. Install it and start signing.

npm install @firma-dev/sdk
npm install @firma-dev/sdk
npm install @firma-dev/sdk

What ships in the TypeScript e-signature SDK

@firma-dev/sdk is the official, fully-typed TypeScript client for the Firma.dev API. Every endpoint is exposed as a typed method, grouped by resource, so you get editor autocomplete and compile-time safety instead of raw HTTP plumbing. The client covers all 66 endpoints: templates, signing requests, webhooks, workspaces, custom fields, email domains, email templates, signer terms, JWT management, and settings.

It runs server-side on Node 18 or later, uses the built-in fetch, ships with zero runtime dependencies, and is MIT licensed. Current release is 0.2.0.

Why a typed e-signature API client matters

The SDK is generated directly from the same OpenAPI specification that powers the API reference. That means the request and response shapes always match the live API. When an endpoint changes, the types change with it, so a mismatched field is a compile error in your editor rather than a 400 you debug in production.

For a SaaS team embedding signing into its own product, this removes a whole category of glue code. No more maintaining a bespoke HTTP layer, no more guessing at payload shapes, no more re-reading the reference every time you touch an endpoint. Agencies automating client signing workflows get the same benefit: build the integration once against typed methods and let the compiler catch drift.

A quick look at @firma-dev/sdk

Authenticate with a single API key. The client sends it on every request and parses responses for you.

import { FirmaClient } from "@firma-dev/sdk";

const firma = new FirmaClient({ apiKey: process.env.FIRMA_API_KEY });

const templates = await firma.templates.listTemplates();
console.log(templates);
import { FirmaClient } from "@firma-dev/sdk";

const firma = new FirmaClient({ apiKey: process.env.FIRMA_API_KEY });

const templates = await firma.templates.listTemplates();
console.log(templates);
import { FirmaClient } from "@firma-dev/sdk";

const firma = new FirmaClient({ apiKey: process.env.FIRMA_API_KEY });

const templates = await firma.templates.listTemplates();
console.log(templates);

Awaiting a method returns the parsed response body directly. When you need the HTTP status or headers, call .withRawResponse():

const { data, rawResponse } = await firma.templates
  .listTemplates()
  .withRawResponse();

console.log(rawResponse.status);
console.log(rawResponse.headers.get("x-request-id"));
const { data, rawResponse } = await firma.templates
  .listTemplates()
  .withRawResponse();

console.log(rawResponse.status);
console.log(rawResponse.headers.get("x-request-id"));
const { data, rawResponse } = await firma.templates
  .listTemplates()
  .withRawResponse();

console.log(rawResponse.status);
console.log(rawResponse.headers.get("x-request-id"));

Failed requests throw a typed FirmaError that carries the status code and the parsed error body, so error handling stays readable:

import { FirmaClient, FirmaError } from "@firma-dev/sdk";

try {
  await firma.templates.getTemplate({ id: "does-not-exist" });
} catch (err) {
  if (err instanceof FirmaError) {
    console.error(err.statusCode); // e.g. 404
    console.error(err.body);       // parsed error payload
  } else {
    throw err;
  }
}
import { FirmaClient, FirmaError } from "@firma-dev/sdk";

try {
  await firma.templates.getTemplate({ id: "does-not-exist" });
} catch (err) {
  if (err instanceof FirmaError) {
    console.error(err.statusCode); // e.g. 404
    console.error(err.body);       // parsed error payload
  } else {
    throw err;
  }
}
import { FirmaClient, FirmaError } from "@firma-dev/sdk";

try {
  await firma.templates.getTemplate({ id: "does-not-exist" });
} catch (err) {
  if (err instanceof FirmaError) {
    console.error(err.statusCode); // e.g. 404
    console.error(err.body);       // parsed error payload
  } else {
    throw err;
  }
}

Keep your API key in an environment variable or a secrets manager, never in client-side code. The SDK is built for server-side use.

Read the full guide. Installation, authentication, quickstart, common operations, error handling, and pagination are all covered in the docs: docs.firma.dev/guides/typescript-sdk. Every endpoint in the API reference now includes a copy-paste @firma-dev/sdk sample, so you can grab a working call for your exact parameters. See the changelog entry v1.28.0 for the full v01.28.00 rundown.

Get started with the Firma.dev SDK

Install the SDK, drop in your API key, and send your first request. Firma.dev is pay-as-you-go at €0.049 per envelope (about 5¢ USD), with no contracts and no monthly minimums.

Get started with Firma.dev for free, no credit card required.

  1. Heading

Background Image

Ready to add e-signatures to your application?

Get started for free. No credit card required. Pay only €0.049 per envelope when you're ready to go live.

Background Image

Ready to add e-signatures to your application?

Get started for free. No credit card required. Pay only €0.049 per envelope when you're ready to go live.

Background Image

Ready to add e-signatures to your application?

Get started for free. No credit card required. Pay only €0.049 per envelope when you're ready to go live.