name: b2c-config
description: Inspect, configure, and troubleshoot the B2C CLI's setup, authentication, and instance connections. Use this skill as the fallback whenever CLI setup, configuration, or authentication is unclear or failing — including "command can't find my instance/credentials", auth errors (401/403, "client credentials required"), wrong sandbox being targeted, env var vs dw.json precedence, hostname mismatch warnings, missing tenantId/shortCode, OAuth scope errors, multi-instance switching, retrieving access tokens for scripts, and IDE/Prophet integration. Also use when the user needs to check what dw.json looks like, what fields it accepts (camelCase or kebab-case keys), or where the CLI is reading config from. Triggers include "why is the CLI connecting to the wrong instance", "auth keeps failing", "what config does the CLI see", "I need an OAuth token", "my dw.json isn't being picked up", or any general "how do I configure the CLI" question.
B2C Config Skill
The B2C CLI (@salesforce/b2c-cli) is a command-line tool for Salesforce B2C Commerce development. It provides commands organized by topic: auth, code, webdav, sandbox, mrt, scapi, slas, ecdn, job, logs, sites, content, cip, setup, and more. Use b2c --help or b2c <topic> --help for a full list.
Tip: If
b2cis not installed globally, usenpx @salesforce/b2c-cliinstead (e.g.,npx @salesforce/b2c-cli setup inspect).
How the CLI Discovers Configuration (read this first)
The CLI automatically detects instance hostname, credentials, tenant ID, MRT API key, and other settings from multiple sources. You usually do not need to pass --server, --client-id, --client-secret, --username, --password, --tenant-id, --short-code, or --api-key as flags — the CLI picks them up from the environment or config files.
Sources, in resolution order (highest priority first):
- CLI flags and environment variables — explicit values always win. Includes
.envfiles in the current project directory (auto-loaded). - Plugin sources (high priority) — custom configuration plugins (e.g., secret managers).
dw.json— searched starting at the current directory and walking up the directory tree. Supports a single instance or aconfigs[]array withactive: true/-i <name>selection.~/.mobify— home-directory file (MRT API key only).- Plugin sources (low priority).
package.jsonunder theb2ckey — non-sensitive project defaults (e.g.,shortCode,clientId,mrtProject). Sensitive fields likeclientSecret/passwordare intentionally not allowed here.
When in doubt, always run b2c setup inspect first — it shows the resolved value and the source for every field. This is the single most useful command for setup confusion.
dw.json Key Casing
Field names in dw.json accept both camelCase and kebab-case — they're equivalent. For example:
| Either form works |
|---|
clientId ≡ client-id |
clientSecret ≡ client-secret |
codeVersion ≡ code-version |
tenantId ≡ tenant-id |
shortCode ≡ short-code ≡ scapi-shortcode |
webdavHostname ≡ webdav-hostname ≡ webdav-server ≡ secureHostname |
certificatePassphrase ≡ certificate-passphrase ≡ passphrase |
Legacy aliases like server (for hostname) are also still supported. If a value isn't being picked up, casing is rarely the cause — check spelling, then run b2c setup inspect to see what the CLI actually parsed.
For the full field reference, see the Configuration guide (or docs/guide/configuration.md in the repo).
Authentication
Most commands that interact with a B2C Commerce instance require authentication. The CLI supports several methods:
- Client credentials (API client): Configure
clientIdandclientSecretin dw.json or environment variables. This is the default for automated/CI use. - Browser-based (implicit OAuth): Use
--user-authon any OAuth-enabled command to authenticate interactively via the browser. This opens Account Manager in your default browser for login. - Basic auth: Configure
usernameandpasswordfor WebDAV operations. - Stateful sessions: Use
b2c auth loginfor persistent browser-based login sessions.
--user-auth Flag
Many commands support --user-auth to use browser-based implicit OAuth instead of client credentials. This is useful when:
- You don't have a
clientSecretconfigured - You need user-level permissions (e.g., Account Manager admin roles)
- You're working interactively
# Interactive browser-based auth for any OAuth command
b2c sandbox list --user-auth
b2c scapi schemas list --user-auth
b2c auth token --user-auth
Coding agents can also use --user-auth — the browser flow works in any environment where a browser can be opened. The flag is exclusive with --auth-methods.
Running behind a proxy: If localhost:8080 isn't reachable by the browser (e.g., running in a container or behind a reverse proxy), set SFCC_REDIRECT_URI to the proxy URL. The local OAuth server still listens on the default port (or SFCC_OAUTH_LOCAL_PORT), but the redirect URI sent to Account Manager will use your proxy URL. Add the proxy URL to the API client's redirect URLs in Account Manager.
Tenant ID and Organization ID
B2C Commerce uses two related identifiers:
- Tenant ID — the short form (e.g.,
zzxy_prdorzzxy-prd) - Organization ID — the SCAPI form with
f_ecom_prefix (e.g.,f_ecom_zzxy_prd)
The CLI automatically normalizes and translates between these formats. You can provide either form in configuration or flags — the CLI handles the conversion. It also extracts tenant IDs from hostnames (e.g., zzxy-prd.dx.commercecloud.salesforce.com resolves to zzxy_prd).
In dw.json or environment variables, use the tenantId config key. The CLI will add the f_ecom_ prefix when making SCAPI calls.
Inspecting Configuration
Use b2c setup inspect to view the resolved configuration and understand where each value comes from. Use b2c setup instance commands to manage named instance configurations.
Note:
b2c setup configworks as an alias forb2c setup inspect.
When to Use
Use b2c setup inspect when you need to:
- Verify which configuration file is being used
- Check if environment variables are being read correctly
- Debug authentication failures by confirming credentials are loaded
- Understand credential source priority (dw.json vs env vars vs plugins)
- Identify hostname mismatch protection issues
- Verify MRT API key is loaded from ~/.mobify
View Current Configuration
# Display resolved configuration (sensitive values masked by default)
b2c setup inspect
# View configuration for a specific instance from dw.json
b2c setup inspect -i staging
# View configuration with a specific config file
b2c setup inspect --config /path/to/dw.json
Debug Sensitive Values
# Show actual passwords, secrets, and API keys (use with caution)
b2c setup inspect --unmask
JSON Output for Scripting
# Output as JSON for parsing in scripts
b2c setup inspect --json
# Pretty-print with jq
b2c setup inspect --json | jq '.config'
# Check which sources are loaded
b2c setup inspect --json | jq '.sources'
IDE Integration (Prophet)
Use b2c setup ide prophet to generate a dw.js bridge script for the Prophet VS Code extension.
# Generate ./dw.js in the current project
b2c setup ide prophet
# Overwrite existing file
b2c setup ide prophet --force
# Custom path
b2c setup ide prophet --output .vscode/dw.js
The generated script runs b2c setup inspect --json --unmask at runtime, so Prophet sees the same resolved config as CLI commands, including configuration plugins. It maps values to dw.json-style keys and passes through Prophet fields like cartridgesPath, siteID, and storefrontPassword when present.
Managing Instances
List Configured Instances
# Show all instances from dw.json
b2c setup instance list
# Output as JSON
b2c setup instance list --json
Create a New Instance
# Interactive mode - prompts for all values
b2c setup instance create staging
# With hostname
b2c setup instance create staging --hostname staging.example.com
# Create and set as active
b2c setup instance create staging --hostname staging.example.com --active
# Non-interactive mode (for scripts)
b2c setup instance create staging \
--hostname staging.example.com \
--username admin \
--password secret \
--force
Switch Active Instance
# Set staging as the default instance
b2c setup instance set-active staging
# Now commands use staging by default
b2c code list # Uses staging
Remove an Instance
# Remove with confirmation prompt
b2c setup instance remove staging
# Remove without confirmation
b2c setup instance remove staging --force
Understanding the Output
The setup inspect command displays configuration organized by category:
- Instance: hostname, webdavHostname (if set), codeVersion
- Authentication (Basic): username, password (for WebDAV)
- Authentication (OAuth): clientId, clientSecret, scopes, authMethods, accountManagerHost (if set), sandboxApiHost (if set)
- TLS/mTLS: certificate, certificatePassphrase, selfSigned (only shown when configured)
- SCAPI: shortCode, tenantId
- Managed Runtime (MRT): mrtProject, mrtEnvironment, mrtApiKey, mrtOrigin (if set)
- Metadata: instanceName (from multi-instance configs)
- Sources: List of all configuration sources that were loaded
Each value shows its source in brackets:
[DwJsonSource]— Value from dw.json file[EnvSource]— Value from an SFCC_* environment variable[MobifySource]— Value from ~/.mobify file[PackageJsonSource]— Value from package.jsonb2ckey- Plugin-provided source names (e.g., a credential plugin)
Configuration Priority
Values are resolved with this priority (highest to lowest):
- CLI flags and environment variables
- Plugin sources (high priority)
- dw.json file
- ~/.mobify file (MRT API key only)
- Plugin sources (low priority)
- package.json
b2ckey
When troubleshooting, check the source column to understand which configuration is taking precedence.
Troubleshooting
Always start with b2c setup inspect — it shows resolved values and their sources. Add --unmask to see full secrets, --json for scripting. If a value isn't where you expect, the source column will tell you which file/env var/plugin won.
Command says "credentials required" or "client-id is required"
- The CLI is not finding
clientId/clientSecret. Runb2c setup inspectand check the OAuth section. - Confirm
dw.jsonexists in the current directory or a parent (the CLI walks up fromcwd). - Confirm
SFCC_CLIENT_ID/SFCC_CLIENT_SECRETenv vars are exported in this shell, not just defined elsewhere. - Credential groups are atomic: if
clientIdcomes from one source andclientSecretfrom a lower-priority one, the lower-priority secret is discarded. Provide both from the same source, or use a higher-priority override.
Command targets the wrong instance
b2c setup inspectwill show the resolved hostname and its source.- For multi-instance
dw.json, theactive: trueconfig is used by default. Override with-i <name>per-command, or change the default withb2c setup instance set-active <name>. SFCC_SERVER(or any env var) overridesdw.json. Unset it if you wantdw.jsonto win.- Hostname mismatch protection: if you pass
--server(orSFCC_SERVER) that differs from thedw.jsonhostname, the CLI ignores all other values fromdw.jsonto prevent mixing credentials across instances. Either match the hostname or pass full credentials explicitly.
dw.json is not being picked up
- Check the
Sourcesblock fromb2c setup inspect— ifDwJsonSourceisn't listed, the file wasn't found. - The CLI searches from the current working directory upward. Run from your project root, set
SFCC_PROJECT_DIRECTORY, or pass--config /path/to/dw.json. - Ensure the file is valid JSON (a parse error silently skips it).
- Field name casing doesn't matter — both
clientIdandclient-idwork. See "dw.json Key Casing" above.
401/403 errors on SCAPI/OCAPI calls
- Confirm the resolved
clientId/clientSecretbelong to the target instance (Account Manager scopes the API client per tenant). - Check OAuth scopes: required scopes vary by command (e.g.,
sfcc.cdn-zones,sfcc.orders). Pass--auth-scopeor setSFCC_OAUTH_SCOPES. - For SCAPI commands, verify
tenantIdis correct — tenant IDs use underscores (zzxy_001), hostnames use hyphens (zzxy-001). The CLI normalizes between them, but a wrong tenant ID will produce 403s.
Missing tenantId / shortCode
- These resolve from
dw.json,SFCC_TENANT_ID/SFCC_SHORTCODE, orpackage.json. Runb2c setup inspectto see which source provided them. - For sandboxes,
tenantIdis derived from the hostname (replace-with_):zzxy-001.dx...→zzxy_001.
MRT commands say "API key required"
MRT_API_KEY(orSFCC_MRT_API_KEY) env var, or~/.mobifyfile ({ "api_key": "..." }).- When using
--cloud-origin <host>, the CLI looks for~/.mobify--<host>instead of plain~/.mobify.
Sensitive values masked in setup inspect
- By default secrets show as
admi...REDACTED. Add--unmaskto see full values when debugging.
Missing values
- If a field shows
-, no source provided it. Check spelling indw.json, env var presence, and plugin output. Remember:clientSecret,password, andmrtApiKeycannot be set viapackage.json— usedw.jsonor env vars.
Wrong source taking precedence
- Review the priority list in "How the CLI Discovers Configuration" above. Common surprise: env vars (or a
.envfile) overridedw.json.
Still stuck
Compare two outputs:
b2c setup inspect --unmask --json > expected.json # in a known-good shell
# ... run the failing command in the broken shell, then:
b2c setup inspect --unmask --json > actual.json
diff expected.json actual.json
The diff usually points directly at the missing or overridden field.
Getting Admin OAuth Tokens
Use b2c auth token to get an admin OAuth access token for Account Manager credentials (OCAPI and Admin APIs). This is useful for testing APIs, scripting, or CI/CD pipelines.
# Get access token (outputs raw token to stdout)
b2c auth token
# Get token with browser-based auth
b2c auth token --user-auth
# Get token with specific scopes (accepts multiple: repeat --auth-scope or comma-separate)
b2c auth token --auth-scope sfcc.orders --auth-scope sfcc.products
b2c auth token --auth-scope "sfcc.orders,sfcc.products"
# Get token as JSON (includes expiration and scopes)
b2c auth token --json
# Use in curl for OCAPI calls
curl -H "Authorization: Bearer $(b2c auth token)" \
"https://your-instance.dx.commercecloud.salesforce.com/s/-/dw/data/v24_1/sites"
The token is obtained using the clientId and clientSecret from your configuration (dw.json or environment variables). If only clientId is configured, or --user-auth is used, an implicit OAuth flow is used (browser-based).
Note: This command returns admin tokens for OCAPI/Admin APIs. For shopper tokens (SLAS), see the b2c-slas skill.
Calling SCAPI Admin APIs (system or custom)? The token must carry the tenant scope
SALESFORCE_COMMERCE_API:<tenant_id>plus the API-specific scopes.b2c auth tokendoes not add the tenant scope for you (unlike the SCAPI subcommands such asb2c scapi custom status), so pass it explicitly:b2c auth token \ --auth-scope "SALESFORCE_COMMERCE_API:zzpq_013" \ --auth-scope sfcc.orders --auth-scope sfcc.products.rwSee the
b2c:b2c-scapi-adminandb2c:b2c-custom-api-developmentskills for details.
More Commands
See b2c setup --help for other setup commands including b2c setup skills for AI agent skill installation.