Public walls
Every brand can have a public page on Akteora: https://akteora.com/b/{slug}, listing its
approved testimonials with their words, a permalink for each one, and structured data for search
engines. This page is for developers who want the same content in their own server-rendered pages,
or who need to know what a brand's public address promises.
A wall shows a testimonial only while all of these hold:
- the brand is public (
is_public: true), and neither it nor its organisation is deleted; - the testimonial is approved and public, not rejected, not deleted, and processed;
- for a video or audio testimonial, its files are published at their permanent public address (see Media), normally a few seconds after the approval.
That is exactly the rule the widget uses, decided by the same function.
Make a brand public
curl -X PATCH https://api.akteora.com/v1/brands/brd_01J8… \
-H "$AUTH" -H 'content-type: application/json' \
-d '{ "is_public": true, "slug": "northwind" }'
{
"id": "brd_01J8…",
"slug": "northwind",
"is_public": true,
"public_wall_url": "https://akteora.com/b/northwind",
"logo_url": "https://cdn.akteora.com/l/Zq3…w.png",
"…": "…"
}
- A public brand's slug is its address, and addresses are shared by every Akteora customer.
Going public, or renaming a public brand, with a slug another public brand holds returns
409naming the address. Some words are reserved and also return409, among themdefault, the slug every organisation's first brand is given, so choose a real one. - A private brand's slug only has to be unique within your organisation, as before.
public_wall_urlis set while the brand is public andnullwhile it is private.- Renaming a public brand moves its page. The old address stops answering within seconds; it is not redirected.
- Making a brand private takes its page down within seconds. Its testimonials are not changed.
Read a wall
These routes need no authentication. They are what akteora.com itself renders from.
curl https://api.akteora.com/public/walls/northwind?page=1
{
"brand": {
"name": "Northwind",
"slug": "northwind",
"logo_url": "https://cdn.akteora.com/l/Zq3…w.png",
"accent_color": "#1a73e8"
},
"wall_url": "https://akteora.com/b/northwind",
"url": "https://akteora.com/b/northwind",
"testimonial_count": 31,
"rating": { "average": 4.8, "count": 27 },
"indexable": true,
"page": 1,
"page_count": 2,
"page_size": 24,
"testimonials": [
{
"id": "sub_01J8Z3…",
"kind": "video",
"name": "Maria Lopez",
"title": "Head of Operations",
"company": "Harbour Dental",
"rating": 5,
"date": "2026-08-30",
"text": "We had the whole team onboarded in an afternoon…",
"video_url": "https://cdn.akteora.com/m/k9Xb…/video.mp4",
"audio_url": null,
"poster_url": "https://cdn.akteora.com/m/k9Xb…/poster.jpg",
"duration_ms": 42000,
"language": "en",
"captions": [{ "start_ms": 0, "end_ms": 2400, "text": "We had the whole team…" }],
"source": null
}
]
}
| Route | Returns |
|---|---|
GET /public/walls/{slug}?page={n} |
One page of a wall: 24 testimonials, newest approval first. |
GET /public/walls/{slug}/testimonials/{id} |
One testimonial with its wall's summary: url is its permalink. |
GET /public/walls |
Every public brand with the id and address of each testimonial on its wall: what a sitemap is built from. |
What these promise:
- Nothing private, ever. A private brand, an unknown slug and a page past the last all return
404, and so does a testimonial that is not on that wall, so you cannot tell them apart. No email address, organisation, brand id or storage key appears; the only id is the testimonial's own, which its permalink is addressed by. textis what the customer said (the transcript of a recording) or wrote, exactly as it appears on the page.captionsare the transcript's timed segments.ratingaverages the collected testimonials that include one, across the whole wall. It isnullwhen none does. A review imported from another site keeps its ownratingbut is never counted in this average (importing reviews).sourceis where an imported review first appeared, such as{ "name": "Google", "url": "…" }, andnullfor a testimonial collected through Akteora. Show it with the review.indexableisfalsefor a wall with fewer than three testimonials. Akteora serves those pages, and their permalinks,noindex, and leaves them out of its sitemap.- Media URLs are the permanent public addresses from Media.
- Freshness: responses may be cached for 60 seconds (the listing for 300). Pages on akteora.com change within seconds of an approval or a withdrawal.
- Rate limits: 300 requests a minute per IP address and slug (120 for the listing), with
RateLimit-*headers on every response. Cache what you render.
On akteora.com
https://akteora.com/b/{slug}is the wall, page one. Page two onwards is/b/{slug}/page/{n}.https://akteora.com/b/{slug}/{id}is a testimonial's permalink, with its own share image.https://akteora.com/sitemap.xmllists every indexable wall, its pages and its permalinks.
Structured data: each wall is a schema.org Organization with an AggregateRating, and each
testimonial that has a rating and a name is a Review. A testimonial without either, and any
review imported from another site, is shown but not marked up. Google may choose not to show star ratings for these pages: its guidelines exclude
reviews that the reviewed business controls, and a brand chooses what it publishes.
When a customer asks to be removed
A customer who gave an email address receives a confirmation with a personal link,
https://akteora.com/remove/{token}. It asks before it does anything; confirming hides the
testimonial everywhere at once and erases it for good (recording, words and details) moments
later. The token exists only in that email. Integrations do not need to do anything, but anything
you copied out of Akteora (an exported file, a re-hosted video) is yours to remove.
POST /public/removals/lookup and POST /public/removals (both with { "token": "…" }) are the
page's own calls; they are listed in the OpenAPI document for completeness.