Testimonials
A testimonial is a customer quote shown on your storefront's credibility strip: who said it, what they said, and optionally a star rating and the product it was about. Testimonials are a Storlaunch built-in — not a module, available on every plan with nothing to enable.
Testimonials belong to exactly one workspace (accountId) and render in curated order (sortOrder ascending, then oldest first). Each may optionally point at one of your own products via productId.
All requests on this page require an sk_* key. See Authentication and API overview.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/testimonials |
Create a testimonial |
GET |
/v1/testimonials |
List all testimonials |
GET |
/v1/testimonials/:id |
Retrieve one testimonial |
PATCH |
/v1/testimonials/:id |
Update one (including reordering) |
DELETE |
/v1/testimonials/:id |
Delete one permanently |
See also Portfolio and Certifications — same conventions.
Create a testimonial
POST /v1/testimonials
authorName and quote are required.
New testimonials are published by default. Unlike products, a testimonial is live on your public storefront the moment you create it. Pass
"published": falseto stage it.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
authorName |
string (1–140) | yes | Who said it. Trimmed. |
quote |
string (1–2000) | yes | The testimonial text. Trimmed. |
authorRole |
string (≤140) | null | no | Their role and company, e.g. "Owner, Kopi Anara". |
rating |
integer 1–5 | null | no | Whole stars only. null renders no rating — it is not the same as 0, which is rejected. |
avatarUrl |
string | null | no | The author's photo. http(s):// URL or a root-relative path such as /api/v1/files/<name>; blob:/data: previews are rejected. Max 2048. |
productId |
string | null | no | One of your own product ids. Another workspace's product is rejected. |
published |
boolean | no | Visible on the public storefront. Default true. |
sortOrder |
integer (≥0) | no | Position, ascending. Default 0. |
Passing "" or null for authorRole clears it.
Response — 201 Created
{
"data": {
"testimonial": {
"id": "tst_01HXAB7K3M9N2P5QRS8TVWXY3Z",
"accountId": "acc_01HX...",
"authorName": "Dewi Rahmawati",
"authorRole": "Owner, Kopi Anara",
"quote": "Our online orders tripled in the first month.",
"rating": 5,
"avatarUrl": "/api/v1/files/dewi.jpg",
"productId": null,
"sortOrder": 0,
"published": true,
"createdAt": "2026-05-13T10:42:00.123Z",
"updatedAt": "2026-05-13T10:42:00.123Z"
}
},
"error": null,
"meta": { "requestId": "req_01HX...", "timestamp": "2026-05-13T10:42:00Z" }
}
Ids are always tst_ + ULID. Note the singular key testimonial.
Errors specific to this endpoint
| Status | error.code |
When |
|---|---|---|
400 |
VALIDATION_ERROR |
authorName or quote empty or over length; rating outside 1–5 or not an integer; avatarUrl a blob:/data: URL. |
400 |
VALIDATION_ERROR |
productId does not name one of your products. |
401 |
UNAUTHORIZED |
Key missing, malformed, or revoked. |
List testimonials
GET /v1/testimonials
Returns every testimonial for the workspace in render order, published and unpublished alike. No pagination, no filters.
Response — 200 OK
{ "data": { "testimonials": [ /* … */ ] }, "error": null, "meta": { /* … */ } }
The list key is testimonials; single-record endpoints use testimonial.
Retrieve one
GET /v1/testimonials/:id
404 RESOURCE_NOT_FOUND when the id does not exist or belongs to another workspace.
Update one
PATCH /v1/testimonials/:id
Partial update; every create field is editable, including sortOrder. An empty body is rejected with 400 VALIDATION_ERROR (no fields to update). Omitting productId leaves the link alone; null clears it.
Response — 200 OK, the full updated record under data.testimonial.
Delete one
DELETE /v1/testimonials/:id
Permanent — the row is destroyed, not archived.
{ "data": { "deleted": true }, "error": null, "meta": { /* … */ } }
The object
| Field | Type | Nullable | Description |
|---|---|---|---|
id |
string | no | tst_ + ULID. |
accountId |
string | no | Owning workspace. |
authorName |
string | no | ≤140. |
authorRole |
string | yes | ≤140. |
quote |
string | no | ≤2000. |
rating |
integer | yes | 1–5, or null for no rating. |
avatarUrl |
string | yes | Author photo. |
productId |
string | yes | Related product; null after that product is deleted. |
sortOrder |
integer | no | Ascending. Default 0. |
published |
boolean | no | Default true. |
createdAt / updatedAt |
string (ISO 8601) | no | Server-managed. |
Product deletion
Deleting a product does not delete testimonials attached to it. The relation is ON DELETE SET NULL: the testimonial survives with productId cleared.
Next
- Portfolio — past work, same conventions.
- Certifications — credentials and badges.
- Products — what
productIdpoints at.