Sensitive values never live in scenarios or nodes. Not in a node parameter, not hardcoded in a mapping, not in a comment. Everything goes into the Secrets table in the integration’s General section.
This includes endpoints. An endpoint is not sensitive in the common sense, but it is environment-specific, and treating it as a secret is what makes the test/production toggle work. The scenario references the secret slot. It never contains the value.
Why the names are fixed
The library maps blueprints onto global fields using a fixed set of secret names. That’s what delivers the core promise: a user adds a blueprint to their workspace, maps nothing, fills in their own secrets, flips one toggle, and it runs.
The moment one blueprint uses api_key instead of token, that promise breaks for that blueprint and the user is back to manual mapping. The naming isn’t a style preference, it’s the library’s API.
- The allowed list is closed.
custom_*is the only free space. - Validate blueprint secret names automatically against the allowed list at creation time.
- If a value is recurring across providers (an auth host, a tenant ID, an account/subaccount identifier), it doesn’t belong in
custom_*, but it belongs in the fixed list.custom_*is for genuinely provider-specific one-offs, and every recurring value that lands there fragments into five different names across five blueprints.
The slots
endpoint= root API domain. The path is appended in the scenario, so storehttps://api.provider.com/, nothttps://api.provider.com/v2/leads.endpoint_auth= token/authorization host, when it differs from the API host. Common with larger providers (auth.provider.comvsapi.provider.com). If auth lives on the same host as the API, this stays empty and the path is appended in the scenario like any other.endpoint_secondary= any secondary endpoint URLtoken= primary token / API key / client ID. Whatever the provider considers the main identifying credential.token_secondary= second token / secret / client secret.token_sign= signing key (HMAC / MD5). Kept separate fromtokenbecause it’s used in a different operation and often rotates on a different schedule.username= basic auth login.password= basic auth password.partner_id= partner / broker / channel identifier.price= lead price (if it is static)redirect_url= return URL. (if it is static)custom_*= anything else, free suffix. Use sparingly, see above.
Every field has a checkbox for a paired test-environment value. Switching between environments is one toggle at the integration level. You dont need to duplicate an integration for sandbox, and encode the environment into the name (token_test, endpoint_sandbox).
Which slot for which auth type
The slot names are generic on purpose. What goes in token is decided by the blueprint’s auth mode, not by what the provider happens to call it in their docs.
Static API key (header or query param)
token– the keyendpoint– API root- Provider calls it
api_key,X-Api-Key,apikey,access_key? Doesn’t matter. It goes intoken.
Basic auth (base64)
username– loginpassword– passwordendpoint– API root- The base64 encoding happens in the blueprint, not in the stored value. Store the two halves separately and let the HTTP module (or an explicit
base64(username + ":" + password)step) build the header. - Do not store a pre-encoded
dGVzdDpwYXNzblob intoken. It can’t be rotated one half at a time, it can’t be paired cleanly with a test value, it’s unreadable in the UI, and nobody six months from now will know which half changed.
Bearer token, long-lived (no refresh)
token– the bearer valueendpoint– API root- The blueprint prepends
Bearer. Don’t store the prefix in the secret – some providers useToken,JWT, or nothing at all, and the prefix is the blueprint’s business.
OAuth2 — client credentials
token– client IDtoken_secondary– client secretendpoint_auth– token host, if it differs from the API hostendpoint– API root- Scope, audience, grant type and the token path are blueprint configuration, not secrets. They’re the same for every user of that provider. Only put a scope in
custom_scopeif it genuinely varies per account.
OAuth2 — authorization code / refresh token
token– client IDtoken_secondary– client secretendpoint_auth– auth hostredirect_url– callback URL registered with the provider- The refresh token is not a secret in this sense. It’s runtime state – it rotates, sometimes on every use. See What must not go into Secrets.
HMAC / signed requests
token– API key or partner identifier sent in the cleartoken_sign– the signing keyendpoint– API root- The signature algorithm, the field order, and what exactly gets hashed are all blueprint logic. They’re identical for every user of the provider, so they don’t belong in Secrets.
Basic auth + separate signing (common in insurance / energy feeds)
username,password– transport-level authtoken_sign– payload signing keypartner_id– the identifier the provider uses to attribute the lead
What must not go into Secrets
Secrets is configuration. It is not state. An access token obtained at runtime does not get written back into the Secrets table. Neither does a rotating refresh token, a session ID, or a cached signature.
Writing runtime tokens back buys you:
- Race conditions. Two parallel scenario runs refresh at the same time and overwrite each other. One of them then holds a token the provider has already invalidated.
- Environment bleed. A cached token from sandbox survives the test/production toggle and gets sent to the live endpoint, or the other way around.
- A useless audit log. The Secrets change history fills with refresh writes, and you can no longer see when a human actually changed a credential.
- Broken rotation. When someone rotates the client secret, you can’t tell which stored value is the credential and which is derived from it.
Instead:
- Keep a separate token cache at the integration level, keyed by
integration_id + environment. - Store the expiry, refresh proactively before it, and refresh reactively on a 401.
- The cache is invisible to the user and clears when credentials change or the environment toggle flips.

