#Widget signing secret
GET /widget-signing-secret
Get the organization's widget signing secret, the key you sign a customer's email with before an authenticated widget can read their data. There is one per organization, and it is created the first time you ask for it.
Requires the settings:read permission.
Request
curl \
"https://api.cascade.dev/widget-signing-secret" \
-H "Authorization: Bearer sk_YOUR_SECRET_KEY"Request
import { client } from "@cascade-commerce/api/admin/client"
import { getWidgetSigningSecret } from "@cascade-commerce/api/admin"
client.setConfig({
baseUrl: "https://api.cascade.dev",
headers: { Authorization: "Bearer sk_YOUR_SECRET_KEY" },
})
const { data, error } = await getWidgetSigningSecret()Request
require "net/http"
uri = URI("https://api.cascade.dev/widget-signing-secret")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer sk_YOUR_SECRET_KEY"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.bodyRequest
import json
from urllib.request import Request, urlopen
req = Request(
"https://api.cascade.dev/widget-signing-secret",
headers={"Authorization": "Bearer sk_YOUR_SECRET_KEY"},
)
with urlopen(req) as res:
print(json.load(res))Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"secret": "string",
"endsWith": "string",
"generatedAt": "2025-01-15T09:30:00Z",
"lastUsedAt": "2025-01-15T09:30:00Z",
"createdAt": "2025-01-15T09:30:00Z"
}Response schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Unique identifier for the signing secret."
},
"secret": {
"type": "string",
"description": "The secret itself. Anyone holding it can sign as any of your customers, so keep it on your server."
},
"endsWith": {
"type": "string",
"description": "The last few characters of the secret, for telling one value from another."
},
"generatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the current secret was generated."
},
"lastUsedAt": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "When a widget request was last signed with it, or null if none ever has been."
},
"createdAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the organization's signing secret was first created."
}
},
"required": ["id", "secret", "endsWith", "generatedAt", "lastUsedAt", "createdAt"],
"additionalProperties": false,
"description": "The organization's widget signing secret."
}POST /widget-signing-secret/rotate
Generate a new widget signing secret. The old one stops working right away, so every storefront still signing with it needs the new value before its shoppers can sign in again. The rotation is recorded in the audit trail.
Requires the settings:write permission.
Request
curl \
-X POST \
"https://api.cascade.dev/widget-signing-secret/rotate" \
-H "Authorization: Bearer sk_YOUR_SECRET_KEY"Request
import { client } from "@cascade-commerce/api/admin/client"
import { postWidgetSigningSecretRotate } from "@cascade-commerce/api/admin"
client.setConfig({
baseUrl: "https://api.cascade.dev",
headers: { Authorization: "Bearer sk_YOUR_SECRET_KEY" },
})
const { data, error } = await postWidgetSigningSecretRotate()Request
require "net/http"
uri = URI("https://api.cascade.dev/widget-signing-secret/rotate")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer sk_YOUR_SECRET_KEY"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.bodyRequest
import json
from urllib.request import Request, urlopen
req = Request(
"https://api.cascade.dev/widget-signing-secret/rotate",
method="POST",
headers={"Authorization": "Bearer sk_YOUR_SECRET_KEY"},
)
with urlopen(req) as res:
print(json.load(res))Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"secret": "string",
"endsWith": "string",
"generatedAt": "2025-01-15T09:30:00Z",
"lastUsedAt": "2025-01-15T09:30:00Z",
"createdAt": "2025-01-15T09:30:00Z"
}Response schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Unique identifier for the signing secret."
},
"secret": {
"type": "string",
"description": "The secret itself. Anyone holding it can sign as any of your customers, so keep it on your server."
},
"endsWith": {
"type": "string",
"description": "The last few characters of the secret, for telling one value from another."
},
"generatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the current secret was generated."
},
"lastUsedAt": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "When a widget request was last signed with it, or null if none ever has been."
},
"createdAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the organization's signing secret was first created."
}
},
"required": ["id", "secret", "endsWith", "generatedAt", "lastUsedAt", "createdAt"],
"additionalProperties": false,
"description": "The new widget signing secret."
}