Documentation

Everything you need. Nothing you don't.

Quickstart

// Every script exports a single function.
// It runs once per incoming webhook.

export default (request, drip, env) => {
  drip("https://api.myapp.com/webhook", request.body)
}

Point Stripe (or anything) at your webhook URL. QueueBaby queues it, runs your script, and delivers to your destination with automatic retries.

The request Object

export default (request, drip, env) => {
  request.method   // "POST"
  request.path     // "/your-route-id"
  request.headers  // { "content-type": "application/json", ... }
  request.body     // parsed JSON payload (or raw string if not JSON)
}

The drip() Function

drip(destination, payload, options?)
export default (request, drip, env) => {
  const billing   = "https://billing.myapp.com/fulfill"
  const analytics = "https://analytics.myapp.com/event"

  // Fan-out at independent rates
  drip(billing, request.body, { rate: 100 })
  drip(analytics, request.body, { rate: 10 })

  // Transform before sending
  drip("https://hooks.slack.com/T00/B00/xxx", {
    text: `New order: $${request.body.amount / 100}`
  })

  // Array shorthand: same payload, multiple destinations
  drip(["https://primary.myapp.com", "https://backup.myapp.com"], request.body)
}

Options

drip(destination, payload, {
  rate: 50,          // deliveries per second (default: your tier's max)
  method: "POST",    // HTTP method (default: POST)
  retries: 12,       // retry attempts w/ exponential backoff (default: 12, max: 20)
  headers: {         // custom headers on the outbound request
    "X-Source": "queuebaby"
  }
})

Limits

Deduplication

export default (request, drip, env) => {
  // Returns true if this key was already seen
  if (env.Dedupe(request.body.id)) return

  // Safe to drip — this event hasn't been processed before
  drip("https://api.myapp.com/hook", request.body)
}

Call env.Dedupe() once at the top. All drips below are safe.

Logging

export default (request, drip, env) => {
  console.log("Received:", request.body.type)   // visible in dashboard logs
  console.error("Something wrong")              // same output, just semantic

  // 100 log statements per execution, 5KB per statement
}

Sandbox

Each execution runs in an isolated WebAssembly sandbox.

// What you CAN'T do:
fetch("https://evil.com")    // ❌ undefined
require("fs")                // ❌ undefined
import("module")             // ❌ not supported

// What you CAN do:
drip("https://myapp.com", d) // ✅ queued and delivered by the engine
console.log("debug")         // ✅ captured in dashboard logs
env.Dedupe("key")            // ✅ deduplication check
JSON.parse(str)              // ✅ standard JS built-ins work

Hard limits: 5MB RAM, 100ms execution time, no network access from inside the script.

Tier Limits

FreeBasicProEnterprise
Deliveries/mo1M10M100MCustom
Payload64KB128KB256KBCustom
Retention3 days7 days30 daysCustom
Dedupe keys10K50K250KCustom

429 Behavior

POST https://ingest.queue.baby/abc123
→ 429 Too Many Requests: Burst limit exceeded

Stripe, GitHub, Shopify — every major provider retries on 429. Your payloads aren't lost.

Full Example

export default (request, drip, env) => {
  const event = request.body

  // Skip duplicates
  if (env.Dedupe(event.id)) return

  const slack = "https://hooks.slack.com/services/T00/B00/xxx"
  const db    = "https://api.myapp.com/webhooks/stripe"

  // Notify Slack
  drip(slack, {
    text: `💰 ${event.data.object.customer_email} — $${event.data.object.amount_total / 100}`
  })

  // Update your database at a controlled rate
  drip(db, event.data.object, {
    rate: 50,
    headers: { "Authorization": `Bearer ${env.secrets.API_KEY}` }
  })
}