sfcc-scapi-custom-endpoints — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited sfcc-scapi-custom-endpoints (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill guides you through developing Custom APIs for Salesforce B2C Commerce under the SCAPI framework.
[ ] Cartridge contains `cartridge/rest-apis/{api-name}/` with schema.yaml, script.js, api.json
[ ] operationId in schema matches exported function name with `.public = true`
[ ] Custom parameters and scopes use the `c_` prefix
[ ] Contract avoids unsupported features (no additionalProperties, only local $ref)
[ ] Shopper APIs include siteId; Admin APIs omit it
[ ] Code version is activated to register endpointshttps://{shortcode}.api.commercecloud.salesforce.com/custom/{api-name}/v{major}/organizations/{org-id}{path}?{params}Version is derived from info.version: "1.2.0" → /v1/, "2.0.0" → /v2/
my_cartridge/
└── cartridge/
└── rest-apis/
└── my-api-name/ # Lowercase alphanumeric + hyphens only
├── api.json # Mapping file
├── schema.yaml # OAS 3.0 contract
└── script.js # Implementationopenapi: 3.0.0
info:
title: My Custom API
version: "1.0.0"
paths:
/my-endpoint:
get:
operationId: getMyData # Must match function name
parameters:
- name: siteId # Required for Shopper APIs
in: query
required: true
schema:
type: string
minLength: 1
- name: c_my_param # Custom params must have c_ prefix
in: query
required: true
schema:
type: string
responses:
'200':
description: Success
security:
- ShopperToken: [c_my_scope]
components:
securitySchemes:
ShopperToken:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://{shortCode}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/{orgId}/oauth2/token
scopes:
c_my_scope: Description'use strict';
var RESTResponseMgr = require('dw/system/RESTResponseMgr');
exports.getMyData = function () {
// Query parameters
var myParam = request.getHttpParameterMap().get('c_my_param').getStringValue();
// Path parameters (for paths like /items/{itemId})
var itemId = request.getSCAPIPathParameters().get('itemId');
// Request body (POST/PUT/PATCH)
var body = JSON.parse(request.httpParameterMap.requestBodyAsString);
// Success response
RESTResponseMgr.createSuccess({ data: myParam }).render();
};
exports.getMyData.public = true; // Required!
// Error response example
exports.getMyDataWithError = function () {
RESTResponseMgr.createError(404, 'not-found',
'Resource Not Found', 'The requested resource was not found.').render();
};
exports.getMyDataWithError.public = true;{
"endpoints": [
{
"endpoint": "getMyData",
"schema": "schema.yaml",
"implementation": "script"
}
]
}Important: Implementation name has NO file extension. All files must be in the same folder.
| Aspect | Shopper API | Admin API |
|---|---|---|
| Security Scheme | ShopperToken | AmOAuth2 |
| siteId Parameter | Required | Must omit |
| Max Runtime | 10 seconds | 60 seconds |
| Max Request Body | 5 MiB | 20 MB |
| Token Source | SLAS | Account Manager |
Custom scopes must:
c_security:
- ShopperToken: [c_read_loyalty] # Global or per-operationEnable Page Caching for the site, then:
// Cache for 60 seconds
response.setExpires(Date.now() + 60000);
// Personalized caching (price/promotion variants)
response.setVaryBy('price_promotion');TTL: minimum 1 second, maximum 86,400 seconds (24 hours).
Custom APIs have a circuit breaker that blocks requests when error rate exceeds 50%:
Prevention: Write robust error handling; avoid uncaught exceptions.
siteId, locale) must have type: string, minLength: 1/baskets response)rest-apis/{api-name}/ structure| Error | Cause | Solution |
|---|---|---|
| 400 Bad Request | Contract violation | Define all params in schema |
| 401 Unauthorized | Invalid/missing token | Check token validity |
| 403 Forbidden | Missing scope | Verify scope in token matches contract |
| 404 Not Found | Endpoint not registered | Check status, verify structure |
| 500 Internal Error | Script error | Check logs for CustomApiInvocationException |
| 503 Service Unavailable | Circuit breaker open | Fix script errors, wait for reset |
Review logs in Log Center with LCQL filter: CustomApiRegistry
GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
Note: GET requests cannot commit transactions.
c_ prefixadditionalProperties in schemas$ref referencesget_sfcc_class_info("dw.system.RESTResponseMgr") // REST response manager
search_sfcc_methods("getCustomer") // Customer retrieval methods
get_sfcc_class_info("dw.svc.ServiceRegistry") // External service integration~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.