Skip to content

Latest commit

 

History

History
192 lines (155 loc) · 6.47 KB

File metadata and controls

192 lines (155 loc) · 6.47 KB
title Quickstart
description Create a template, send it from your app, then change the copy without a redeploy.
icon rocket

In about five minutes you'll do the one thing that makes SenderKit different: create a message template in the dashboard, wire up a single send call, and then change the wording from the dashboard — no code change, no redeploy. The subject, layout, and copy live outside your repo; your code just names the template and fills in the variables.

In the [dashboard](https://senderkit.com/app/templates), create an `email` [template](/concepts/templates) with the slug `welcome`. Write a subject and body, and reference dynamic values as [variables](/concepts/variables) with Mustache braces:
```text Template copy (in the dashboard editor)
Subject: Welcome to Acme, {{name}} 👋

Hi {{name}},

Thanks for signing up — we're glad you're here.
```

The slug `welcome` is the stable name your code will send to. Staring at a blank
editor? [AI authoring](/concepts/ai-authoring) drafts the subject, layout, and
variables from a one-line brief.

<Tip>
  You don't need to publish yet. In test mode SenderKit renders your **latest
  draft**, so you can keep editing copy as you go. Live sends only ever render the
  [published version](/concepts/versioning).
</Tip>
Create a key in the [dashboard](https://senderkit.com/app/api-keys). Use an `sk_test_` key while you're wiring things up — test keys never call your providers, so nothing reaches a real inbox — and switch to `sk_live_` to send for real. The plaintext is shown once at creation, so copy it then. Reference the template by slug, pass the recipient and `vars`, and send. Pick your surface:
<Tabs>
  <Tab title="TypeScript SDK">
    Install the SDK:

    <CodeGroup>
      ```bash npm
      npm install @senderkit/sdk
      ```

      ```bash pnpm
      pnpm add @senderkit/sdk
      ```

      ```bash yarn
      yarn add @senderkit/sdk
      ```

      ```bash bun
      bun add @senderkit/sdk
      ```
    </CodeGroup>

    Keep your key in the environment (out of source), then create a client and send:

    ```bash
    export SENDERKIT_API_KEY="sk_test_..."
    ```

    ```ts
    import { SenderKit } from "@senderkit/sdk";

    const senderkit = new SenderKit({ apiKey: process.env.SENDERKIT_API_KEY! });

    const result = await senderkit.send({
      template: "welcome",
      to: "user@example.com",
      vars: { name: "Ada" },
    });

    console.log(result); // { id: "msg_…", status: "queued", livemode: false }
    ```

    The core SDK has zero runtime dependencies and uses native `fetch` (Node.js 18+).
    Keep the key server-side — never ship it in a client bundle.
  </Tab>

  <Tab title="cURL">
    ```bash
    curl -X POST https://api.senderkit.com/v1/send \
      -H "Authorization: Bearer sk_test_..." \
      -H "Content-Type: application/json" \
      -d '{
        "template": "welcome",
        "to": "user@example.com",
        "vars": { "name": "Ada" }
      }'
    ```

    Returns `202 Accepted`:

    ```json
    { "id": "msg_…", "status": "queued", "livemode": false }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash
    npm install -g @senderkit/cli
    senderkit login          # paste your sk_test_… key when prompted
    senderkit send welcome user@example.com --vars '{"name":"Ada"}'
    ```

    ```
    ✓ Queued message msg_…
    id:     msg_…
    status: queued
    mode:   test
    ```

    See the full [CLI reference](/cli/send) for options like `--metadata` and
    `--scheduled-at`.
  </Tab>
</Tabs>

`vars` fills the `{{name}}` holes in your template. Sends are asynchronous: the call
returns `status: "queued"` once SenderKit accepts the message (or `"scheduled"` if you
passed a future `scheduledAt`), and delivery happens out of band.
The send is accepted immediately as `queued` and delivered asynchronously — in test mode without ever touching a real provider, so nothing reaches an inbox. Look the message up in the dashboard, or fetch it by the `id` you got back:
```ts
const message = await senderkit.messages.get(result.id);
console.log(message.status, message.timeline);
```

You can also list recent sends with `senderkit.messages.list({ template: "welcome" })`
(CLI: `senderkit messages list`; HTTP: `GET /v1/messages`). See
[Messages](/concepts/messages) for how a send moves from queued to delivered.
Here's the payoff. Go back to the `welcome` template in the dashboard, change the subject or body, and run the **exact same send again**. The new wording renders — you didn't touch a line of code or ship a deploy.
That's the whole idea: `send({ template: "welcome" })` is a stable contract, and
everything that changes without engineering — the words, the layout, the subject —
lives on the dashboard side of it. Anyone on the team can fix a typo without opening
your editor.
**Publish** the `welcome` template, then swap your key to `sk_live_`. No code changes — SenderKit [derives live vs. test](/concepts/environments) from the key prefix, and your published template renders for real.

What's next

Trigger this send automatically from a Clerk or Auth.js event. Key types, scopes, and the test vs. live model. Slugs, channels, and why copy edits never touch your code. Track a send from queued to delivered. Working with an AI assistant? The [MCP server](/mcp/overview) exposes these same operations to agents in Claude, Cursor, and other MCP clients.