Environments

Zeplo doesn’t enforce a specific environment model — you organize things however works best for your team.

Recommended patterns

Separate workspaces

The cleanest approach: create separate workspaces for development, staging, and production. Each gets its own queues, tokens, and billing.

  • acme-dev — development workspace
  • acme-staging — staging workspace
  • acme-prod — production workspace

Token-per-environment

If you prefer a single workspace, use separate API tokens for each environment. This makes it easy to track which requests came from where.

Bypassing the queue in development

During local development, you may want to call your endpoints directly (synchronously) instead of going through Zeplo. This makes debugging easier since errors are thrown immediately.

const ZEPLO_TOKEN = process.env.ZEPLO_TOKEN
const ZEPLO_QUEUE_ID = process.env.ZEPLO_QUEUE_ID
const IS_PROD = process.env.NODE_ENV === 'production'

async function enqueue(method, url, body) {
  if (!IS_PROD) {
    // Call directly in development
    return fetch(url, { method, body, headers: { 'Content-Type': 'application/json' } })
  }

  // Queue via Zeplo in production
  return fetch(`https://v2-api.zeplo.io/queues/${ZEPLO_QUEUE_ID}/enqueue`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${ZEPLO_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ method, url, body }),
  })
}

Securing your endpoints

Since Zeplo makes HTTP requests to your endpoints on the public internet, you should authenticate these requests. A simple approach:

// Generate a secret: https://zelark.github.io/nano-id-cc/
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET

app.post('/my-webhook', (req, res) => {
  if (req.headers['x-webhook-secret'] !== WEBHOOK_SECRET) {
    return res.status(401).json({ error: 'Unauthorized' })
  }
  // Process the request...
})

Then include the secret in your enqueue headers:

{
  "method": "POST",
  "url": "https://your-api.com/my-webhook",
  "headers": {"X-Webhook-Secret": "your-secret-here"},
  "body": "..."
}