SkillRouter
Documentation menu

Operate

Deployment

Deploy the web and API services with separate trust boundaries.

Required topology

  1. Deploy the API service behind TLS with database and shared rate-limit access.
  2. Set NODE_ENV=production and an explicit public listener such as HOST=0.0.0.0.
  3. Configure server-only provider, Stripe, hashing, session, and observability secrets.
  4. Set ERROR_MONITOR_WEBHOOK_URL to a plain HTTPS endpoint that accepts SkillRouter JSON error events, and set a separate ERROR_MONITOR_WEBHOOK_TOKEN of at least 32 characters; it is not a Sentry DSN.
  5. Set DASHBOARD_ORIGINS to the exact deployed web origin and verify credentialed CORS.
  6. Set TRUST_PROXY_CIDRS to the exact reverse-proxy ranges allowed to supply forwarding headers.
  7. Run database migrations and curated seed data before serving traffic.
  8. Build the web app with explicit bare HTTPS API and site origins plus NEXT_PUBLIC_SKILLROUTER_DEMO_MODE=false. Do not add paths, credentials, queries, or fragments.
  9. Verify session-cookie origin, CORS, Stripe webhook signatures, health checks, and kill switches.

Production gates

  • Keep OPENROUTER_PRODUCTION_RESALE_ENABLED=false until commercial authorization is recorded.
  • Treat environment flags as hard upper bounds and enable the matching audited database flags separately.
  • Keep AUTO_SETUP_DATABASE=false and run compiled db:migrate and db:seed as separate deployment jobs.
  • Set per-request output limits and account, key, token, concurrency, and spend controls.
  • Use a shared production rate-limit store; do not depend on process memory.
  • Alert on daily upstream spend, provider failure rate, margin anomalies, and stream disconnects.
  • Alert on error_monitor_delivery_failure; network errors and non-2xx webhook responses increment it.
  • Test backup restoration and payment-ledger reconciliation before launch.

Stripe webhook

Register https://api.useskillrouter.com/webhooks/stripe with its own signing secret. A checkout redirect does not credit the ledger.

Implemented events
checkout.session.completed
checkout.session.async_payment_succeeded
refund.created
refund.failed
charge.dispute.created
charge.dispute.funds_withdrawn
charge.dispute.funds_reinstated
Local Stripe forwarding
stripe listen \
  --events checkout.session.completed,checkout.session.async_payment_succeeded,refund.created,refund.failed,charge.dispute.created,charge.dispute.funds_withdrawn,charge.dispute.funds_reinstated \
  --forward-to localhost:3001/webhooks/stripe

When a created refund fails, refund.failed restores the related credits or account deficit idempotently. Test both successful and failed refund paths.