Five products · live in production

Stop rewriting the same backendon every new project.

Auth, Mail, Waitlist, Social and Trawl — five REST APIs behind one account, one API key and typed Node SDKs. Install the parts you keep rebuilding; build the part only you can.

Each service has a free tier large enough to ship a side project on. Pricing is coming soon.

npm install productcraft
server.ts
import { ProductCraft } from "productcraft";

const pc = new ProductCraft({
  auth: {
    type: "apiKey",
    key: process.env.PCFT_KEY!,
  },
});

// Auth — sign in an EndUser
const consumer = pc.auth.consumer("my-app");
const tokens = await consumer.auth.signin({
  identifier: "alice@example.com",
  password: "...",
});
REST-first, SDK-optional. Server-side only — every path here is in the OpenAPI spec the docs render from.

The lineup

Five products. One workspace.

Use one or all five. Each is its own REST API with its own docs, npm package and console pages; the account, the API key and the workspace are shared.

The boring half

Authlive

Sign-in for your users, tenants included.

  • Passkeys — Face ID, Touch ID, security keys — on their own or as a second factor.
  • Sign in with Apple, Google or GitHub; TOTP or email one-time codes as MFA, with recovery codes.
  • Tenants with org roles in the token; per-app signing keys at /.well-known/jwks.json; M2M client credentials.
  • Signed webhooks and an append-only audit log with export.

In the console: Apps · End users · Roles · Tenants · Passkeys · Audit

Maillive

Send from your domain, not ours.

  • A DKIM keypair per domain; you add the DNS records once and verify with a TXT challenge.
  • Idempotency-Key on template sends (per row in a batch) — a retry replays the original response for 24 hours.
  • Signed delivery and bounce webhooks; bounces feed the suppression list automatically.
  • Bring your own relay — SES, SendGrid, Mailgun — per workspace or per domain.

ProductCraft's own transactional email goes through it.

In the console: Domains · SMTP relay · Templates · Messages · Suppression list

Waitlistlive

Signups that don't live in a spreadsheet.

// No auth — public surface
POST /v1/waitlists/{workspace_slug}
     /{waitlist_slug}/entries
// → { id, position }
  • A public POST your landing page calls with no API key.
  • Referral codes, positions and a leaderboard; variants for A/B/n landing pages.
  • Approve an entry and invite it straight into your Auth app; signed webhooks and CSV export.

In the console: Overview · Waitlists · Webhooks · Settings

The interesting half

trawl.ts
Trawllive
import { Trawl } from "@productcraft/trawl";

const trawl = new Trawl({
  auth: {
    type: "apiKey",
    key: process.env.PCFT_KEY!,
  },
});

const { data, error } =
  await trawl.client.POST(
    "/v1/workspaces/{workspaceId}/jobs",
    {
      params: {
        path: { workspaceId: "<workspace-uuid>" },
      },
      body: {
        description:
          "Extract the product title " +
          "and price from each page.",
        json_schema: {
          type: "object",
          properties: {
            title: { type: "string" },
            price: { type: "number" },
          },
          required: ["title"],
        },
        suggested_urls: [
          "https://example.com/product",
        ],
      },
    },
  );

if (error) throw error;
console.log(data.id, data.status);
// → "<job-uuid>", "queued"

Structured data from any URL, without selectors.

  • POST a JSON Schema and a one-sentence description; a browser agent returns data that conforms.
  • Results arrive on an HMAC-signed webhook and stay on the job record — poll any time.
  • Rotate the webhook secret, test it, read the delivery log, cancel a job.

In the console: Jobs · Webhooks

Sociallive

Feeds, follows and ranking without the rewrite.

POST /v1/communities/{communityId}
     /posts
X-Acting-As: <actor_id>
{
  "actor_id": "<actor-uuid>",
  "text": "Hello, world!",
  "visibility": "public"
}
  • Standalone — no Auth app required.
  • Ranked or chronological feeds tuned per community; a follow graph with requests and suggestions.
  • Stories with polls and close friends, DMs, notifications, a moderation queue, video up to 512 MB.

In the console: Overview · Analytics · Moderation · Settings

Pick the one that brought you here. The other four are already in your workspace.

One workspace

One workspace. One cookie. One mental model.

Sign in once at auth.productcraft.co and every product trusts the same session. A workspace owns your apps, domains, templates, waitlists, communities, jobs and API keys, and the console shows the same workspace for all five.

  • restEvery product publishes its OpenAPI document; the API reference and the SDKs render from it.
  • api_keypcft_live_… keys carry an IAM-style policy — author once, bind to any key.
  • sdk@productcraft/auth · @productcraft/mail · @productcraft/waitlist · @productcraft/social · @productcraft/trawl, plus the productcraft umbrella. Node.js / TypeScript, server-side, MIT.
  • webhooksSigned webhooks on Auth, Mail, Waitlist and Trawl, each with rotate-secret and a delivery log; Waitlist and Trawl add test delivery.
  • idempotencyIdempotency-Key on Mail sends: a retry replays the original response for 24 hours.
  • auditA workspace audit log in the console; Auth keeps a per-app, append-only log with export; every MCP call is logged.
POST /{app_slug}/v1/authorize
{
  "token":      "eyJhbGciOiJSUzI1NiIs...",
  "permission": "user.read"
}

→ { "authorized": true }

From your editor

Claude, Cursor and VS Code can work in your workspace.

An MCP server at mcp.productcraft.co. You approve the connection in the browser, a policy preset caps what it may do, and every call lands in the audit log.

  • OAuth in the browser — no API key in a config file.
  • Presets: readonly, mail, support, full. Nothing that escalates privilege is ever in a preset.
  • Owners revoke any connection from the console.
MCP docs
terminal
claude mcp add --transport http productcraft https://mcp.productcraft.co/mcp

# then, inside Claude Code:
/mcp        # pick "productcraft" and follow the browser prompt

Note what is not in any of those snippets: a token, a key, a client id, a secret. The only configuration is the URL.

Changelog

Shipped, dated, linked.

Every entry is a production deploy. The full list is on the changelog.

Read the changelog
Pick a door

Drop in the boring half. Get back to the rest.

Open a workspace, create an API key, call the product that brought you here. The other four are on the same key.