Skip to main content
Every provider whose per-environment state Sponson manages, by category: what it manages, the op or recipe that does it, the credential it reads from the environment (where to create it, and what to pick: sponson init --setup walks through the same), what sponson init detects it by, and a line to start from. sponson init reads dependency names, config files and variable names (never their values) and writes these lines for every provider it detects: ready to apply when it knows every value, else commented out with a # TODO: that says where to find each missing one. 64 providers in 13 categories: 17 ops of first-class adapters and 68 recipe ops, plus 3 steps no API reaches, tracked as manual.step lines. sponson init detects 59 providers.

Deploy targets and their environment variables

Vercel

Env vars per target and git branch; wait for the preview deployment, redeploy if it built before the write.
  • Ops: vercel.env, vercel.deploy
  • Credential: VERCEL_TOKEN
  • Token: create it: A token whose Scope is the team that owns the project, with an expiration. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: vercel, @vercel/*, vercel.json, .vercel/project.json, VERCEL_*

Netlify

Env var values per deploy context (deploy-preview, branch + context_parameter); wait for the deploy of the commit, rebuild if it started before the write.
  • Ops: netlify.env
  • Credential: NETLIFY_AUTH_TOKEN
  • Token: create it: A personal access token (Netlify tokens have no scopes) with an expiration; allow access to a SAML-protected team if yours enforces SSO. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: @netlify/*, netlify-cli, netlify.toml, .netlify/state.json, NETLIFY_*

Cloudflare Pages / Workers

Pages: deployment_configs.preview.env_vars (all previews share one set, no per-branch values). Workers: secrets per script / preview version (Pages variables; Workers secrets are not covered).
  • Ops: cloudflare.pages_env
  • Credential: CLOUDFLARE_API_TOKEN
  • Token: create it: A custom token with Account > Cloudflare Pages > Edit, limited to the one account. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: wrangler, @cloudflare/next-on-pages, wrangler.json, wrangler.jsonc, wrangler.toml, CLOUDFLARE_*

Render

Env vars on a preview service / preview environment (per variable on a service whose id the plan gives (Render creates previews itself; no lookup of PR N’s service); writing does not deploy).
  • Ops: recipe render.env_var
  • Credential: RENDER_API_KEY (bearer)
  • Token: create it: An API key; Render keys have no scopes and reach every workspace of the user who creates them. sponson init --setup checks it with GET /owners.
  • Detected by sponson init from: render.yaml, RENDER_*

Railway

Variables in a PR environment (Railway creates PR environments natively) (the PR environment’s id is a param; Sponson does not wait for the redeploy a write triggers).
  • Ops: recipe railway.variable
  • Credential: RAILWAY_API_TOKEN (bearer)
  • Token: create it: A workspace token for the workspace that holds the project. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: railway.json, railway.toml, RAILWAY_*

Fly.io

Per-PR app (the usual pattern is one app per PR) plus its secrets (secrets before the PR’s deploy; a later change needs fly secrets deploy).
  • Ops: recipe fly_machines.app, recipe fly.secret
  • Credential: FLY_API_TOKEN (bearer)
  • Token: create it: An org token (fly tokens create org): it creates and deletes apps in the organization. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Token: create it: A deploy token for the one app (fly tokens create deploy -a <app>), or an org token (fly tokens create org) for an app per PR. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: fly.toml, FLY_*

Heroku

Review app per PR; config vars on it (config vars on an existing app (a review app by name); creating the review app (async, by Heroku’s automatic review apps) is not managed).
  • Ops: recipe heroku.config_var
  • Credential: HEROKU_API_KEY (bearer)
  • Token: create it: A long-lived authorization from heroku authorizations:create -s write-protected: the narrowest scope that reads and writes config vars. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: heroku.yml, HEROKU_*

AWS Amplify

Branch (per-PR previews built in); env vars per branch (variables before the branch’s first build (no rebuild)).
  • Ops: recipe amplify.branch, recipe amplify.branch_variable
  • Credential: AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (AWS SigV4, amplify in us-east-1)
  • Token: create it: An IAM user’s access key whose policy allows amplify:ListApps, amplify:GetBranch, amplify:CreateBranch, amplify:UpdateBranch and amplify:DeleteBranch on the app. sponson init --setup checks it with GET /apps.
  • Detected by sponson init from: amplify.yml

Google Cloud Run

Tagged revision per PR (--tag pr-42), env vars on it (a revision of an existing service per scope from its template, with the plan’s image and variables, tagged and given no traffic (traffic on LATEST is pinned only with the line’s pin_latest: true, refused otherwise); destroy removes the tag and Cloud Run deletes the revision later).
  • Ops: cloud_run.revision
  • Credential: the token gcloud auth print-access-token prints (bearer)
  • Token: set up access: Sign in with gcloud auth login as an identity holding Cloud Run Developer (roles/run.developer) and Service Account User on the service’s runtime service account. sponson init --setup shows this; there is no token to store.
  • Detected by sponson init from: @google-cloud/run, CLOUD_RUN_*, K_SERVICE

Azure Static Web Apps

Preview environment per PR (built in); app settings (after the PR’s first deploy (the environment exists only then)).
  • Ops: recipe azure_swa.build_app_setting
  • Credential: the token az account get-access-token --query accessToken -o tsv prints (bearer)
  • Token: set up access: Sign in with az login as an identity holding Contributor on the static web app (or a custom role with Microsoft.Web/staticSites/*). sponson init --setup shows this; there is no token to store.
  • Detected by sponson init from: staticwebapp.config.json, AZURE_STATIC_WEB_APPS_*

DigitalOcean App Platform

No native PR previews; app per PR via its GitHub action; envs in the app spec (an app per scope from a whole spec, waited for until deployed (in place of the app DigitalOcean’s GitHub action makes); secret values are not compared).
  • Ops: digitalocean.app
  • Credential: DIGITALOCEAN_ACCESS_TOKEN
  • Token: create it: A personal access token with Custom Scopes: app:read and app:update. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: .do/app.yaml, .do/deploy.template.yaml, DIGITALOCEAN_*

Firebase Hosting

Preview channel per PR (pr-42) that the preview is deployed into, with its own web.app URL; deleted when the PR closes instead of left to expire (the channel only: deploying into it stays firebase hosting:channel:deploy (which also authorizes its domain in Firebase Auth); its url is an output).
  • Ops: recipe firebase_hosting.channel
  • Credential: the token gcloud auth print-access-token prints (bearer)
  • Token: set up access: Sign in with gcloud auth login (or activate a service account) as an identity holding Firebase Hosting Admin (roles/firebasehosting.admin) on the project. sponson init --setup shows this; there is no token to store.
  • Detected by sponson init from: .github/workflows/firebase-hosting-pull-request.yml

Databases with branching or per-PR instances

Neon

Copy-on-write branch per PR, connection string out.
  • Ops: neon.branch
  • Credential: NEON_API_KEY
  • Token: create it: A project-scoped API key for the one project (an organization admin creates it); otherwise a personal API key. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: @neondatabase/*, @prisma/adapter-neon, neonctl, .neon, NEON_*, database URL on *.neon.tech

Supabase

Preview branch per PR (a separate project with its own ref, keys and URL).
  • Ops: supabase.branch
  • Credential: SUPABASE_ACCESS_TOKEN
  • Token: create it: A personal access token limited to the project, with Development Branches, Auth Config and Project Settings set to Read-write. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: @supabase/*, supabase/config.toml, supabase/.temp/project-ref, SUPABASE_*, database URL on *.supabase.co, database URL on *.supabase.com

PlanetScale

Branch per PR; password (credential) per branch; deploy request on merge (deploy requests on merge are not managed).
  • Ops: planetscale.branch, planetscale.password
  • Credential: PLANETSCALE_SERVICE_TOKEN_ID + PLANETSCALE_SERVICE_TOKEN
  • Token: create it: A service token with create_branch, delete_branch, read_branch and connect_branch (and delete_branch_password) on the one database. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: @planetscale/*, PLANETSCALE_*, database URL on *.psdb.cloud

Turso

Database branched from a parent (seed: {type: database}), token per DB.
  • Ops: recipe turso.database_branch
  • Credential: TURSO_API_TOKEN (bearer)
  • Token: create it: A platform API token for the organization (turso auth api-tokens mint <name> --org <org>). sponson init --setup checks it with GET /auth/validate.
  • Detected by sponson init from: @libsql/client, @tursodatabase/*, TURSO_*, database URL on *.turso.io

Xata

Copy-on-write Postgres branch (waits until the branch is healthy; only its existence is compared for drift).
  • Ops: xata.branch
  • Credential: XATA_API_KEY
  • Token: create it: An API key limited to the project, with Branch: Read and Write. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: @xata.io/*, .xatarc, XATA_*

MongoDB Atlas

No branching; per-PR database user and database name on a shared cluster (cluster per PR is slow and costly) (the password is an input ({ secret }, or a sensitive output of another line), sent on create only and never compared).
  • Ops: recipe mongodb_atlas.database_user
  • Credential: MONGODB_ATLAS_PUBLIC_API_KEY / MONGODB_ATLAS_PRIVATE_API_KEY (HTTP Digest)
  • Token: create it: A project API key with Project Network Access Manager (access list) or Project Database Access Admin (database users), and an API access list entry. sponson init --setup checks it with GET /groups.
  • Detected by sponson init from: MONGODB_ATLAS_*, database URL on *.mongodb.net

CockroachDB Cloud

No branching; per-PR database is SQL (CREATE DATABASE), a cluster per PR is infra (the Cloud API creates databases and SQL users (cockroachdb.sql_user, which gets the SQL admin role by default); grants narrower than that still need SQL).
  • Ops: recipe cockroachdb.database, recipe cockroachdb.sql_user
  • Credential: COCKROACH_API_KEY (bearer)
  • Token: create it: A service account (Access Management > Service Accounts) with the Cluster Admin role on the cluster, then Create API Key. sponson init --setup checks it with GET /clusters.
  • Detected by sponson init from: COCKROACH_*, database URL on *.cockroachlabs.cloud

Prisma Postgres

Database per PR in a project, connection string per database (connection strings are once-only outputs (in the create answer only); Sponson does not wait for status ready).
  • Ops: recipe prisma.database, recipe prisma.database_copy
  • Credential: PRISMA_SERVICE_TOKEN (bearer)
  • Token: create it: A workspace service token (Workspace Settings > Service Tokens); it covers the whole workspace, with no finer scopes. sponson init --setup checks it with GET /projects.
  • Detected by sponson init from: @prisma/ppg, database URL on *.prisma.io, database URL on *.prisma-data.net

Auth callback and redirect allow-lists

Clerk

Preview URL on the instance’s redirect allow-list.
  • Ops: clerk.redirect_allow
  • Credential: CLERK_SECRET_KEY
  • Token: create it: The Secret Key of the instance whose redirect URLs the plan manages (sk_test_ for development); Clerk secret keys have no scopes. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: @clerk/*, CLERK_*

Auth0

Preview URL in an application’s callbacks, allowed_logout_urls, web_origins, allowed_origins.
  • Ops: recipe auth0.callback_url, recipe auth0.logout_url, recipe auth0.web_origin, recipe auth0.allowed_origin
  • Credential: AUTH0_CLIENT_ID / AUTH0_CLIENT_SECRET (OAuth2 client credentials)
  • Token: create it: A Machine to Machine application authorized for the Auth0 Management API with only the read:clients and update:clients scopes. sponson init --setup checks it with GET /clients.
  • Detected by sponson init from: auth0, @auth0/*, AUTH0_*

Supabase Auth

Preview URL in “Additional Redirect URLs”.
  • Ops: supabase.auth_redirect
  • Credential: SUPABASE_ACCESS_TOKEN
  • Token: create it: A personal access token limited to the project, with Development Branches, Auth Config and Project Settings set to Read-write. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: @supabase/*, supabase/config.toml, supabase/.temp/project-ref, SUPABASE_*, database URL on *.supabase.co, database URL on *.supabase.com

Firebase Auth

Preview domain in authorizedDomains.
  • Ops: recipe firebase.authorized_domain
  • Credential: the token gcloud auth print-access-token prints (bearer)
  • Token: set up access: Sign in with gcloud auth login as an identity holding Firebase Authentication Admin (roles/firebaseauth.admin) on the project. sponson init --setup shows this; there is no token to store.
  • Detected by sponson init from: firebase, firebase-admin, firebase.json, .firebaserc, FIREBASE_*

WorkOS

Redirect URI for AuthKit.
  • Ops: recipe workos.redirect_uri
  • Credential: WORKOS_API_KEY (bearer)
  • Token: create it: The secret API key of the environment (staging for previews); WorkOS keys have no finer permissions. sponson init --setup checks it with GET /organizations.
  • Detected by sponson init from: @workos-inc/*, WORKOS_*

Stytch

Redirect URL per environment.
  • Ops: recipe stytch.redirect_url
  • Credential: STYTCH_WORKSPACE_KEY_ID / STYTCH_WORKSPACE_KEY_SECRET (basic)
  • Token: create it: A Workspace Management API key (Workspace settings > Management API); its key ID and secret, no finer scopes. sponson init --setup checks it with GET /pwa/v3/projects.
  • Detected by sponson init from: stytch, @stytch/*, STYTCH_*

Okta

redirect_uris on an OIDC app; trusted origin for CORS.
  • Ops: recipe okta.redirect_uri, recipe okta.post_logout_redirect_uri, recipe okta.trusted_origin
  • Credential: OKTA_API_TOKEN (header Authorization, after SSWS)
  • Token: create it: An API token (Security > API > Tokens) created by an admin whose role can edit the app (it acts with that admin’s permissions). sponson init --setup checks it with GET /users/me.
  • Detected by sponson init from: @okta/*, OKTA_*

Kinde

Callback and logout URLs on an application.
  • Ops: recipe kinde.callback_url, recipe kinde.logout_url
  • Credential: KINDE_MANAGEMENT_CLIENT_ID / KINDE_MANAGEMENT_CLIENT_SECRET (OAuth2 client credentials)
  • Token: create it: A Machine to Machine application authorized for the Kinde Management API with only the application redirect and logout URI scopes. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: @kinde-oss/*, KINDE_*

Google OAuth clients

Preview URL in a web client’s authorized redirect URIs.
  • Ops: manual.step
  • Credential: none (a person does it)
  • Detected by sponson init from: not detected (write the line yourself)

Feature flags and targeting

LaunchDarkly

Flag on for a preview: target a context key or add a rule on url, in a per-PR or shared preview environment (context-key targets; url rules not yet).
  • Ops: launchdarkly.flag_target
  • Credential: LAUNCHDARKLY_ACCESS_TOKEN
  • Token: create it: An access token whose custom role allows updateTargets on the environment’s flags and viewProject (without custom roles: the Writer role). sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: @launchdarkly/*, launchdarkly-node-server-sdk, launchdarkly-js-client-sdk, launchdarkly-react-client-sdk, LAUNCHDARKLY_*

PostHog

Release condition matching the preview host on a flag (condition on a person or group property; needs the merging filters PATCH of current PostHog (PH5)).
  • Ops: recipe posthog.release_condition
  • Credential: POSTHOG_PERSONAL_API_KEY (bearer)
  • Token: create it: A personal API key with only the feature_flag:read and feature_flag:write scopes, limited to the project (EU: eu.posthog.com). sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: posthog-js, posthog-node, posthog-react-native, POSTHOG_*

Statsig

Gate rule for the preview (condition url or environment_tier) (gates requiring reviews: write behaviour undocumented (SG8)).
  • Ops: recipe statsig.gate_rule
  • Credential: STATSIG_CONSOLE_API_KEY (header STATSIG-API-KEY)
  • Token: create it: A Console API key (Project Settings > API Keys) that can edit gates. sponson init --setup checks it with GET /gates.
  • Detected by sponson init from: statsig-js, statsig-node, statsig-react, @statsig/*, STATSIG_*

GrowthBook

Force rule in a per-environment feature (v2 API (rules with per-rule environments); approval-gated features refuse the write).
  • Ops: recipe growthbook.force_rule
  • Credential: GROWTHBOOK_API_KEY (bearer)
  • Token: create it: A Secret API key (Settings > API Keys) with a role that can edit features, limited to the project. sponson init --setup checks it with GET /v1/features.
  • Detected by sponson init from: @growthbook/*, GROWTHBOOK_*

Unleash

Strategy (with constraints) on a flag in an environment (deleting the last strategy turns the flag off in that environment (UN8)).
  • Ops: recipe unleash.flag_strategy
  • Credential: UNLEASH_AUTH_TOKEN (header Authorization)
  • Token: create it: A personal access token (or an Enterprise service account token) whose role edits flags and strategies in the project; not a client or frontend token. sponson init --setup checks it with GET /api/admin/projects.
  • Detected by sponson init from: unleash-client, unleash-proxy-client, @unleash/*, UNLEASH_*

Flagsmith

Segment override or a per-PR environment (a per-PR environment (its client-side key is an output); identity and segment overrides are not recipes: Edge identities are addressed by UUID, and a segment override is two objects created in order).
  • Ops: recipe flagsmith.environment
  • Credential: FLAGSMITH_MASTER_API_KEY (header Authorization, after Api-Key)
  • Token: create it: An Organisation API key (Organisation Settings > API Keys); with role-based access, give it a role limited to the project. sponson init --setup checks it with GET /organisations/.
  • Detected by sponson init from: flagsmith, flagsmith-nodejs, react-native-flagsmith, FLAGSMITH_*

ConfigCat

Targeting rule on a setting in an environment (boolean flags; products requiring a change reason or approval refuse the write).
  • Ops: recipe configcat.targeting_rule
  • Credential: CONFIGCAT_BASIC_AUTH_USERNAME / CONFIGCAT_BASIC_AUTH_PASSWORD (basic)
  • Token: create it: Public Management API credentials; they act with your user’s product permissions, so use a member limited to the product. sponson init --setup checks it with GET /v1/me.
  • Detected by sponson init from: configcat-js, configcat-js-ssr, configcat-js-full, configcat-node, configcat-react, CONFIGCAT_*

Split (Harness FME)

Targeting rule / individual target in an environment (targeting rule (not individual targets); projects requiring title/comment refuse the write).
  • Ops: recipe split.targeting_rule
  • Credential: SPLIT_ADMIN_API_KEY (bearer)
  • Token: create it: An Admin API key (Admin settings > API keys), restricted to the environments the lines change. sponson init --setup checks it with GET /workspaces.
  • Detected by sponson init from: @splitsoftware/*, SPLIT_*

Webhooks registered per environment

Stripe

Test-mode webhook endpoint pointing at the preview URL; its signing secret into the app’s env.
  • Ops: recipe stripe.webhook_endpoint
  • Credential: STRIPE_SECRET_KEY (bearer)
  • Token: create it: A test-mode restricted key (Create restricted key) with Webhook Endpoints set to Write and everything else None. sponson init --setup checks it with GET /webhook_endpoints.
  • Detected by sponson init from: stripe, @stripe/*, STRIPE_*

GitHub

Repository webhook to the preview URL.
  • Ops: recipe github.repo_webhook
  • Credential: GITHUB_TOKEN (bearer)
  • Token: create it: A fine-grained token for the one repository with the permission the line’s op needs (Webhooks, Administration or Environments: Read and write). sponson init --setup checks it with GET /user.
  • Detected by sponson init from: @octokit/webhooks, probot, GITHUB_WEBHOOK_SECRET

Svix (as a sender)

Endpoint per environment on an application.
  • Ops: recipe svix.endpoint
  • Credential: SVIX_AUTH_TOKEN (bearer)
  • Token: create it: The environment’s API key (API Access); keys have no finer scopes. sponson init --setup checks it with GET /api/v1/app.
  • Detected by sponson init from: svix, SVIX_*

Clerk webhooks

Preview URL as a webhook endpoint.
  • Ops: manual.step
  • Credential: none (a person does it)
  • Detected by sponson init from: not detected (write the line yourself)

Twilio

TwiML Application whose voice (and messaging, status) URLs are the preview’s, named by the preview’s Voice SDK tokens; a shared phone number has one URL and is not per-preview state (per-preview inbound SMS or calls need a number per preview (bought, A2P-registered for US SMS); a shared number’s single URL is not managed, and subaccounts (closed, never deleted, numbers bought per subaccount) are not the model).
  • Ops: recipe twilio.twiml_app
  • Credential: TWILIO_API_KEY / TWILIO_API_SECRET (basic)
  • Token: create it: A Standard API key (Console > Account > API keys & tokens); its SID goes in TWILIO_API_KEY and its secret in TWILIO_API_SECRET. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: twilio, TWILIO_*

Ably

Integration rule (webhook) posting the preview’s channels’ messages or presence to the preview URL (the app (shared) and its keys are parent objects; the preview’s channels must carry a per-preview prefix for a filter to tell them apart).
  • Ops: recipe ably.webhook_rule
  • Credential: ABLY_CONTROL_TOKEN (bearer)
  • Token: create it: An account access token (Account > My Access Tokens) with the read:rule and write:rule capabilities only. sponson init --setup checks it with GET /me.
  • Detected by sponson init from: ably, ABLY_*

Email: sending domains, webhooks, test inboxes

Resend

Restricted API key or webhook per environment (domains are long-lived; test addresses like delivered@resend.dev need no API).
  • Ops: recipe resend.api_key, recipe resend.webhook
  • Credential: RESEND_API_KEY (bearer)
  • Token: create it: An API key with Full access: Sending access can only send email, not manage webhooks, domains or keys. sponson init --setup checks it with GET /domains.
  • Detected by sponson init from: resend, RESEND_*

Postmark

Server per environment, webhook per server (chained in one plan by a line credential (ADR 0017, Line credentials): the webhook line says destroy: keep, since its webhooks go with the server; scenarios/adapters/http-line-credential.yaml).
  • Ops: recipe postmark.server, recipe postmark_server.webhook
  • Credential: POSTMARK_ACCOUNT_TOKEN (header X-Postmark-Account-Token); POSTMARK_SERVER_TOKEN (header X-Postmark-Server-Token)
  • Token: create it: The Account API token (Account Owner or Admin only); Postmark tokens have no scopes. sponson init --setup checks it with GET /servers.
  • Token: create it: The server’s Server API token (the server’s API Tokens tab); Postmark tokens have no scopes. sponson init --setup checks it with GET /server.
  • Detected by sponson init from: postmark, POSTMARK_*

SendGrid

Event webhook or inbound-parse host per environment.
  • Ops: recipe sendgrid.event_webhook, recipe sendgrid.parse_setting
  • Credential: SENDGRID_API_KEY (bearer)
  • Token: create it: A Restricted Access key with Mail Settings > Event Notification set to Full Access. sponson init --setup checks it with GET /v3/scopes.
  • Detected by sponson init from: @sendgrid/*, SENDGRID_*

Mailgun

Webhook delivering email events to the preview URL, or an inbound route forwarding a per-preview address to it (sending and receiving domains are long-lived) (every account webhook receives every domain’s events, and an event type takes three URLs at most: three previews at a time; per-domain webhooks (a list per event, or a map keyed by URL) are not used).
  • Ops: recipe mailgun.webhook, recipe mailgun.route
  • Credential: MAILGUN_API_KEY (basic, user api)
  • Token: create it: An account API key (Account Settings > API Keys): Domain Sending Keys ‘only allow sending messages’ and cannot manage webhooks or routes. sponson init --setup checks it with GET /v1/webhooks.
  • Detected by sponson init from: mailgun.js, mailgun-js, MAILGUN_*

Observability per release

Sentry

Release for the commit, deploy record for the environment; finalize.
  • Ops: recipe sentry.release, recipe sentry.deploy
  • Credential: SENTRY_AUTH_TOKEN (bearer)
  • Token: create it: An organization auth token (Settings > Auth Tokens), or a personal token with project:releases. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: @sentry/*, sentry.client.config.ts, sentry.client.config.js, sentry.server.config.ts, sentry.server.config.js, sentry.properties, .sentryclirc, SENTRY_*

Datadog

Deployment marker / synthetic test against the preview URL (covered by a Synthetic API test against the preview URL; deployment markers stay out of reach (a later run could not find the event it made)).
  • Ops: recipe datadog.synthetic_api_test
  • Credential: DD_API_KEY (header DD-API-KEY) and DD_APP_KEY (header DD-APPLICATION-KEY)
  • Token: create it: An API key, plus an Application key (Organization Settings > Application Keys) limited to the scopes the lines need. sponson init --setup checks it with GET /validate.
  • Detected by sponson init from: dd-trace, @datadog/*, DD_*, DATADOG_*

Honeycomb

Marker per deploy in the environment’s dataset.
  • Ops: recipe honeycomb.marker
  • Credential: HONEYCOMB_API_KEY (header X-Honeycomb-Team)
  • Token: create it: An environment Configuration Key (Manage Environments > API Keys) with only the permission the lines need, such as Manage Markers. sponson init --setup checks it with GET /1/auth.
  • Detected by sponson init from: @honeycombio/*, HONEYCOMB_*

New Relic

Deployment marker (change tracking) on the environment’s entity per release (an http.action (ADR 0022) sent once per entity and version; markers are history (no undo); a preview needs its own entity, or it marks production’s charts).
  • Ops: recipe newrelic.deployment
  • Credential: NEW_RELIC_API_KEY (header API-Key)
  • Token: create it: A user key (NRAK-…, API keys > Create a key > User) of a user who can create change tracking events for the entity’s account. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: newrelic, @newrelic/*, NEW_RELIC_*

Rollbar

Deploy of the revision in the environment (preview) per release (an http.action sent once per environment and revision; deploys are history (no delete in the API)).
  • Ops: recipe rollbar.deploy
  • Credential: ROLLBAR_ACCESS_TOKEN (header X-Rollbar-Access-Token)
  • Token: create it: A project access token with the post_server_item scope (‘Can perform all POST requests to /deploy/ and /item/’). sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: rollbar, @rollbar/*, ROLLBAR_*

BugSnag

Build (release) of the app version in the environment’s release stage per deploy (an http.action sent once per version and release stage; releases are history (no undo)).
  • Ops: recipe bugsnag.build
  • Credential: none of Sponson’s (calls a URL the line gives; a key it needs is a { secret } param)
  • Detected by sponson init from: @bugsnag/*, BUGSNAG_*

DNS and preview domains

Cloudflare DNS

CNAME pr-42.preview.example.com → the preview.
  • Ops: recipe cloudflare.dns_cname
  • Credential: CLOUDFLARE_API_TOKEN (bearer)
  • Token: create it: A custom token (or the Edit zone DNS template) with Zone > DNS > Edit, its Zone Resources limited to the zone. sponson init --setup checks it with GET /user/tokens/verify.
  • Detected by sponson init from: wrangler, @cloudflare/next-on-pages, wrangler.json, wrangler.jsonc, wrangler.toml, CLOUDFLARE_*

Vercel domains

Branch-bound project domain (gitBranch) for a stable preview hostname.
  • Ops: recipe vercel.project_domain
  • Credential: VERCEL_TOKEN (bearer)
  • Token: create it: A token scoped to the team that owns the project, with an expiration. sponson init --setup checks it with GET /v2/user.
  • Detected by sponson init from: vercel, @vercel/*, vercel.json, .vercel/project.json, VERCEL_*

CORS and allowed origins

Firebase Storage (GCS bucket)

Preview origin in the bucket’s cors.
  • Ops: recipe gcs.bucket_cors
  • Credential: the token gcloud auth print-access-token prints (bearer)
  • Token: set up access: Sign in with gcloud auth login as an identity holding Storage Admin (roles/storage.admin) on the bucket: storage.buckets.get and storage.buckets.update. sponson init --setup shows this; there is no token to store.
  • Detected by sponson init from: @google-cloud/storage

S3 / R2

Preview origin in the bucket CORS rules.
  • Ops: recipe s3.bucket_cors
  • Credential: AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (AWS SigV4, s3 in us-east-1)
  • Token: create it: AWS: an access key whose policy allows s3:GetBucketCORS and s3:PutBucketCORS on the bucket. R2: an API token with Admin Read & Write. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: @aws-sdk/client-s3

Sanity CORS

Preview origin in the project’s CORS origins, so browser code, an embedded Studio or the Presentation tool on the preview can query the Content Lake (previews that fetch only on the server need none; allowCredentials is set on create (no update is documented)).
  • Ops: recipe sanity.cors_origin
  • Credential: SANITY_AUTH_TOKEN (bearer)
  • Token: create it: A robot token of the project (API → Tokens) with the Administrator role, or Developer on Growth and Enterprise: editors cannot create datasets, and CORS origins are project settings. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: sanity, @sanity/client, next-sanity, sanity.config.ts, sanity.config.js, sanity.cli.ts, sanity.cli.js, SANITY_*

Queues, caches, background jobs

Upstash Redis

Database per PR, REST URL and token out.
  • Ops: recipe upstash.redis_database
  • Credential: UPSTASH_EMAIL / UPSTASH_API_KEY (basic)
  • Token: create it: A Developer API key (Account > Developer API) with Read/Write; the account’s email is its user name. sponson init --setup checks it with GET /redis/databases.
  • Detected by sponson init from: @upstash/redis, UPSTASH_REDIS_*

Upstash QStash

Schedule that calls the preview URL.
  • Ops: recipe qstash.schedule
  • Credential: QSTASH_TOKEN (bearer)
  • Token: create it: The QStash token of the region (QStash tab); it has no scopes. sponson init --setup checks it with GET /v2/schedules.
  • Detected by sponson init from: @upstash/qstash, QSTASH_*

Inngest

Sync the preview deployment into its branch environment (an http.action (ADR 0022): PUT to the deployment’s serve endpoint once per deployment URL and revision, no Inngest credential; the app must set INNGEST_ENV (automatic on Vercel); nothing to undo (branch environments archive themselves); the beta REST v2 sync endpoint is not used (no way to target a branch environment)).
  • Ops: recipe inngest.sync
  • Credential: none of Sponson’s (calls a URL the line gives; a key it needs is a { secret } param)
  • Detected by sponson init from: inngest, INNGEST_*

Search, payments test mode

Algolia

Index per environment, copied from a template index (copies records, settings, synonyms and rules (or a scope of them) and waits for the copy task; only the index’s existence is compared for drift).
  • Ops: algolia.index
  • Credential: ALGOLIA_API_KEY
  • Token: create it: A restricted API key (not the Admin key) with the addObject, deleteIndex, editSettings, settings and listIndexes ACLs. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: algoliasearch, @algolia/*, instantsearch.js, react-instantsearch, ALGOLIA_*

Stripe test-mode objects

Products / prices / coupons the preview’s code expects.
  • Ops: recipe stripe.product, recipe stripe.price, recipe stripe.coupon
  • Credential: STRIPE_SECRET_KEY (bearer)
  • Token: create it: A test-mode restricted key (Create restricted key) with Webhook Endpoints set to Write and everything else None. sponson init --setup checks it with GET /webhook_endpoints.
  • Detected by sponson init from: stripe, @stripe/*, STRIPE_*

Stripe sandboxes

A sandbox per PR.
  • Ops: manual.step
  • Credential: none (a person does it)
  • Detected by sponson init from: not detected (write the line yourself)

Headless CMS content per preview

Contentful

Sandbox environment per PR copied from master (entries, assets, content types, locales), readable by the app’s delivery and preview API keys; deleted when the PR closes (waits until the copy is ready; the key’s other environments are left alone; a space holds at most 151 environments and plans include fewer sandboxes (2 to 4 below Enterprise)).
  • Ops: contentful.environment, contentful.api_key_access
  • Credential: CONTENTFUL_MANAGEMENT_TOKEN
  • Token: create it: A personal access token (or an OAuth token) with the content_management_manage scope, of a user whose role may create and delete sandbox environments and edit API keys in the space. sponson init --setup checks it with one read-only request.
  • Detected by sponson init from: contentful, contentful-management, @contentful/*, CONTENTFUL_*

Sanity

Dataset per PR for the preview’s content (empty, imported or seeded by the app; or a Cloud Clone copy of production on Enterprise) (an empty dataset per scope; Cloud Clone copies are not covered. Free and Growth include 2 datasets in all, so one preview dataset at a time below Enterprise).
  • Ops: recipe sanity.dataset
  • Credential: SANITY_AUTH_TOKEN (bearer)
  • Token: create it: A robot token of the project (API → Tokens) with the Administrator role, or Developer on Growth and Enterprise: editors cannot create datasets, and CORS origins are project settings. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: sanity, @sanity/client, next-sanity, sanity.config.ts, sanity.config.js, sanity.cli.ts, sanity.cli.js, SANITY_*

Backend platforms with preview deployments

Convex

Preview deployment per PR (its own functions, data and URL), its deploy key for the preview’s build; deleted when the PR closes instead of left to expire (the deployment and a deploy key for it (a once-only output, for CONVEX_DEPLOY_KEY); pushing code stays npx convex deploy).
  • Ops: recipe convex.preview_deployment, recipe convex.deploy_key
  • Credential: CONVEX_TEAM_ACCESS_TOKEN (bearer)
  • Token: create it: A team access token (Team Settings → Access Tokens), preferably of a service-account member: it can do what that member’s role allows on the team. sponson init --setup cannot check it (no read-only request every such credential may send).
  • Detected by sponson init from: convex, convex.json, CONVEX_*