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.

  • Improvement
    Guided setup for Sign in with Google, GitHub and Apple

    Setting up Google, GitHub or Apple sign-in for an Auth app is now five steps in the console, from the provider console link to a real Try sign-in, and every save tells you straight away whether the provider accepts your credentials. New docs guides for Google and GitHub.

  • Improvement
    The same Webhooks screens in Waitlist, Trawl and Social, and one webhooks guide

    Waitlist, Trawl and Social now have the same Webhooks pages in the console as Mail and Auth: add several endpoints, pick events from described lists, Send test and see what your server answered, browse the event log and replay. Trawl shows a banner when your credits run low, and one guide explains signatures, retries and replay for every product.

  • Feature
    Social webhooks: one endpoint for every community, Send test and replay

    A workspace-level Social webhook endpoint now receives the events of every community in the workspace, so you configure one receiver instead of one per community. Social webhooks also gain a Send test that shows what your server answered, a 30-day event log with replay, event descriptions, and Standard Webhooks signatures.

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.