notificationSettings, checkoutSettings) are initialized with defaults. Webhooks are managed separately via add-webhook — no rows exist on a freshly created store.
POST /v1/actions/store/create-store
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Store name (1-48 characters, auto-trimmed) |
Example Request
import { WaffoPancake } from "@waffo/pancake-ts";
const client = new WaffoPancake({
merchantId: process.env.WAFFO_MERCHANT_ID!,
privateKey: process.env.WAFFO_PRIVATE_KEY!,
});
const { store } = await client.stores.create({ name: "My Digital Store" });
console.log(store.id); // => "STO_2aUyqjCzEIiEcYMKj7TZtw"
console.log(store.slug); // => "my-digital-store-a1b2c3"
// Uses callApi() helper from authentication.mdx
const result = await callApi("POST", "/v1/actions/store/create-store", {
name: "My Digital Store",
});
console.log(result.data.store.id); // => "STO_2aUyqjCzEIiEcYMKj7TZtw"
console.log(result.data.store.slug); // => "my-digital-store-a1b2c3"
// Uses callApi() helper from authentication.mdx
String body = """
{"name":"My Digital Store"}""";
String response = callApi("POST", "/v1/actions/store/create-store", body);
System.out.println(response);
// => {"data":{"store":{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","slug":"my-digital-store-a1b2c3",...}}}
# Uses call_api() helper from authentication.mdx
result = call_api("POST", "/v1/actions/store/create-store", {
"name": "My Digital Store",
})
store = result["data"]["store"]
print(store["id"]) # => "STO_2aUyqjCzEIiEcYMKj7TZtw"
print(store["slug"]) # => "my-digital-store-a1b2c3"
// Uses callAPI() helper from authentication.mdx
body := map[string]interface{}{
"name": "My Digital Store",
}
result, err := callAPI("POST", "/v1/actions/store/create-store", body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(result))
// => {"data":{"store":{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","slug":"my-digital-store-a1b2c3",...}}}
// Uses call_api() helper from authentication.mdx
let body = serde_json::json!({
"name": "My Digital Store"
});
let result = call_api("POST", "/v1/actions/store/create-store", &body).await?;
println!("{}", result);
// => {"data":{"store":{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","slug":"my-digital-store-a1b2c3",...}}}
/* Uses call_api() helper from authentication.mdx */
const char *body = "{\"name\":\"My Digital Store\"}";
char *response = call_api("POST", "/v1/actions/store/create-store", body);
printf("%s\n", response);
free(response);
// Uses callApi() helper from authentication.mdx
std::string body = R"({"name":"My Digital Store"})";
std::string response = callApi("POST", "/v1/actions/store/create-store", body);
std::cout << response << std::endl;
// => {"data":{"store":{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","slug":"my-digital-store-a1b2c3",...}}}
MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
TIMESTAMP=$(date +%s)
BODY='{"name":"My Digital Store"}'
BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 | tr -d '\n')
CANONICAL_REQUEST="POST
/v1/actions/store/create-store
$TIMESTAMP
$BODY_HASH"
SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 | tr -d '\n')
curl -X POST "https://api.waffo.ai/v1/actions/store/create-store" \
-H "Content-Type: application/json" \
-H "X-Merchant-Id: $MERCHANT_ID" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Signature: $SIGNATURE" \
-d "$BODY"
MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
TIMESTAMP=$(date +%s)
BODY='{"name":"My Digital Store"}'
BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 | tr -d '\n')
CANONICAL_REQUEST="POST
/v1/actions/store/create-store
$TIMESTAMP
$BODY_HASH"
SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 | tr -d '\n')
wget -qO- "https://api.waffo.ai/v1/actions/store/create-store" \
--header="Content-Type: application/json" \
--header="X-Merchant-Id: $MERCHANT_ID" \
--header="X-Timestamp: $TIMESTAMP" \
--header="X-Signature: $SIGNATURE" \
--post-data="$BODY"
Success Response (200)
{
"data": {
"store": {
"id": "STO_2aUyqjCzEIiEcYMKj7TZtw",
"name": "My Digital Store",
"status": "active",
"logo": null,
"supportEmail": null,
"website": null,
"slug": "my-digital-store-a1b2c3",
"prodEnabled": false,
"notificationSettings": {
"emailOrderConfirmation": true,
"emailSubscriptionConfirmation": true,
"emailSubscriptionCycled": true,
"emailSubscriptionCanceled": true,
"emailSubscriptionRevoked": true,
"emailSubscriptionPastDue": true,
"notifyNewOrders": true,
"notifyNewSubscriptions": true
},
"checkoutSettings": {
"defaultDarkMode": false,
"light": {
"checkoutLogo": null,
"checkoutColorPrimary": "#000000",
"checkoutColorBackground": "#FFFFFF",
"checkoutColorCard": "#F5F5F5",
"checkoutColorText": "#1A1A1A",
"checkoutBorderRadius": "8px"
},
"dark": {
"checkoutLogo": null,
"checkoutColorPrimary": "#FFFFFF",
"checkoutColorBackground": "#1A1A1A",
"checkoutColorCard": "#2A2A2A",
"checkoutColorText": "#F5F5F5",
"checkoutBorderRadius": "8px"
}
},
"deletedAt": null,
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-01-15T10:30:00.000Z"
}
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Store ID (Short ID format STO_xxx) |
name | string | Store display name |
status | string | Store status (active, inactive, or suspended) |
logo | string | null | Store logo URL |
supportEmail | string | null | Support email address |
website | string | null | Store website URL |
slug | string | null | Auto-generated URL slug |
prodEnabled | boolean | Whether production mode is enabled |
notificationSettings | object | null | Notification preferences (see Notification Settings) |
checkoutSettings | object | null | Checkout page theme (see Checkout Settings) |
deletedAt | string | null | Soft-delete timestamp (ISO 8601), null if active |
createdAt | string | Creation timestamp (ISO 8601) |
updatedAt | string | Last update timestamp (ISO 8601) |
Errors
Retry policy: Never retry 4xx — fix the request and resubmit. Retry 5xx with exponential backoff (start 5s, max 3 attempts).
| Status | errors[0].message | What it means | Recommended handling |
|---|---|---|---|
| 400 | Missing merchantId in request context | API Key did not resolve to a merchant context | Do not retry. Check your API Key configuration. |
| 400 | Missing required field: name | name is absent from the body | Fix the input and resubmit. |
| 400 | Store name cannot be empty or contain only whitespace | name is empty after trim() | Fix the input and resubmit. |
| 400 | Store name cannot exceed 48 characters | name is longer than 48 characters | Shorten the name and resubmit. |
| 400 | Store name cannot contain control characters | name contains control characters | Remove the control characters and resubmit. |
| 400 | Cannot create more stores. Maximum limit of 20 stores per merchant has been reached. | The merchant already owns 20 stores | Do not retry. Delete an existing store first, or contact support to raise the limit. |
Each merchant can create up to 20 stores. The store creator is automatically assigned the
owner role.