GenieOSdocs

Quickstart

Send your first transactional email in five minutes — curl, Node, or Python.

This walkthrough takes a brand-new GenieOS workspace and sends a transactional email from your machine. It assumes nothing — no SDK installed, no domain configured, no credit card on file. We use the sandbox key so you can run every command end-to-end without burning a real send.

Create a sandbox key

Go to app.genieos.pro → Settings → API keys, click New key, and choose Sandbox. Copy the key (gos_test_...); it will only be shown once.

Add your own address to the key's sandbox allowlist — sandbox keys can only send to allowlisted recipients.

Why sandbox?

Sandbox keys exercise the entire API — validation, schema contract, webhooks, audit log — but never contact a real mailbox. GenieOS writes a sandbox send, emits send.queued, then a clearly marked synthetic send.delivered (or another scenario) after about two seconds.

Set the key in your shell

zsh / bash
export GENIEOS_API_KEY="gos_test_..."

For long-lived setups, use a .env file or your secrets manager. Never commit a key — see Authentication for rotation.

Subscribe a webhook first

Pick any HTTPS URL you can hit — for local dev, ngrok, cloudflared, or a webhook.site URL all work.

curl https://api.genieos.pro/v1/webhooks \
  -H "Authorization: Bearer $GENIEOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-tunnel.example/genieos",
    "events": ["send.queued", "send.delivered", "send.bounced"],
    "description": "Local dev"
  }'

The response includes a signing secret. Save it: you will need it to verify every payload. See Webhooks for the verifier.

Send your first email

Live path today is template-keyed send (aliases under /v1/transactional/* are not required for the loop):

curl https://api.genieos.pro/v1/templates/welcome/send \
  -H "Authorization: Bearer $GENIEOS_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "you@example.com",
    "variables": { "first_name": "Ada" },
    "metadata": { "order_id": "ord_demo_1" }
  }'
src/send.ts
import { GenieOS } from '@genie-os/sdk';

// GENIEOS_API_KEY=gos_test_… (sandbox) or gos_live_… (production)
const gos = new GenieOS({ apiKey: process.env.GENIEOS_API_KEY! });

const res = await gos.templates.send('welcome', {
  to: 'you@example.com',
  variables: { first_name: 'Ada' },
  metadata: { order_id: 'ord_demo_1' },
});

console.log(res.id);
install (pick your package manager)
npm install @genie-os/sdk
node --env-file=.env --import tsx src/send.ts
send.py
from genieos import GenieOS

# GENIEOS_API_KEY=gos_test_… (sandbox) or gos_live_… (production)
gos = GenieOS()  # reads GENIEOS_API_KEY

res = gos.templates.send(
    "welcome",
    to="you@example.com",
    variables={"first_name": "Ada"},
    metadata={"order_id": "ord_demo_1"},
)

print(res.id)
install (pick your package manager)
pip install genieos
python send.py

Optional sandbox body field: "simulationScenario": "hard_bounce" (or soft_bounce / complained / failed). Default is delivered.

Confirm the loop

Within a few seconds your webhook should receive:

  1. send.queued — GenieOS accepted the send
  2. send.delivered (default) with data.simulation: { "sandbox": true, "scenario": "delivered" }

No mailbox accepted the message — the simulation marker is the proof.

Poll the same send:

curl "https://api.genieos.pro/v1/sends/<id>" \
  -H "Authorization: Bearer $GENIEOS_API_KEY"

List recent sends:

curl "https://api.genieos.pro/v1/sends?limit=25" \
  -H "Authorization: Bearer $GENIEOS_API_KEY"

Promote to production

When you are ready, swap the sandbox key for a gos_live_* key. The two keys share the same workspace, so templates and webhooks set up against sandbox work in production. Live keys contact your workspace connector (MailerSend / Relay / BYO ESP) and emit real send.delivered from the provider — still not on API accept (send.queued ≠ delivered).

Always send Idempotency-Key on production sends.

What just happened

  • Authentication — bearer token with workspace scope; see Authentication.
  • Idempotency — mutating requests carry an Idempotency-Key; see Idempotency.
  • Schema contract — required template variables are validated before accept; see Schema contract.
  • Events + webhookssend.* lifecycle; see Webhooks.

Next: pick a language SDK, install the MCP for your AI editor, or jump straight to the API reference.

On this page