Akteora API docs

The widget: testimonials on any website

One snippet shows a brand's approved testimonials on any page: Shopify, WordPress, Webflow, Squarespace, or HTML you write yourself. It never calls the Akteora API. It reads a static document from Akteora's CDN, so a busy page costs you nothing, and it keeps working even if Akteora's API is down.

The snippet

Create a widget in the dashboard (or with POST /v1/widgets) and paste its snippet:

<div data-akteora-widget="wgt_01J8Z3Y4X5W6V7T8S9R0Q1P2N3" style="height:320px"></div>
<script src="https://cdn.akteora.com/w.js" async></script>

Shopify

In the theme editor, add a Custom Liquid section (or edit a template) and paste the snippet.

WordPress

Add a Custom HTML block and paste the snippet.

Webflow and Squarespace

Use an Embed element (Webflow) or a Code block (Squarespace).

What visitors get

On the free plan, widgets show a small "Collect testimonials with Akteora" link. Paid plans can switch it off (show_attribution: false); on the free plan that request is refused with 402 plan_limit_exceeded.

What a widget shows

Only testimonials that are approved and public, not rejected or deleted, and processed. Nothing else ever reaches the document, however the widget selects:

selection Shows
automatic The brand's newest approvals first; narrowed by tag_ids (any of them) and min_rating
manual Exactly submission_ids, in that order. A pick that is no longer public is skipped

At most max_items (up to 50). fields chooses what each card shows: avatar, name, title, company, rating, date. A field switched off is left out of the published document, not just hidden.

A heading above the testimonials

header adds a title, an optional line under it, and the brand's star rating and review count. It is off until you turn it on, and the avatars layout never draws one: that layout is a one-line summary already.

header setting Default
enabled false Draw the heading
title "What our customers say" Up to 100 characters
subtitle null Up to 200 characters; null or empty for none
show_rating true The average, as stars and a number
show_count true "Based on 112 reviews" beside a rating; "40 testimonials" without one
title_color null #rrggbb; null follows the theme, on light and dark pages alike
text_color null The line under the title and the count; null follows the theme

As with fields, only the settings you send change. The rating and count cover every approved, public testimonial of the brand, the same numbers as its public wall, not just the ones this widget shows. A widget narrowed to five-star reviews still shows the brand's real average.

Turning the heading on makes the snippet reserve 104px more, so paste the new snippet. An old, shorter box still draws everything, with less room for the cards.

A video appears once its files are published (see Media), a few seconds after approval. When you approve, withdraw, edit or delete, the widget's document is rebuilt within a few seconds, then visitors' browsers may keep their copy for up to a minute.

How the widget changes over time

New layouts, looks and card options will be added. What already works keeps working:

The routes

GET /v1/widgets?brand_id=… A brand's widgets, newest first
POST /v1/widgets Create one. Only brand_id is required
GET /v1/widgets/{id} One widget, with its snippet
PATCH /v1/widgets/{id} Change settings. Within fields, only the fields given change
DELETE /v1/widgets/{id} Delete it. Its document goes within seconds; pages keep an empty box
POST /v1/widgets/preview The document a draft would publish, without saving anything
curl -X POST -H "$AUTH" -H 'content-type: application/json' \
  https://api.akteora.com/v1/widgets \
  -d '{ "brand_id": "brd_…", "layout": "carousel", "fields": { "date": true },
        "header": { "enabled": true, "subtitle": "Real words from real customers." } }'

The response includes snippet, height, script_url, document_url, and published_at: null until the first publication a few seconds after creation.

The document

If you would rather draw testimonials yourself, read the widget's document_url. It is public, cached, has no credentials and no expiry, and is served with Access-Control-Allow-Origin: *.

{
  "version": 1,
  "widget_id": "wgt_01J8Z3Y4X5W6V7T8S9R0Q1P2N3",
  "generated_at": "2026-09-13T12:00:00.000Z",
  "layout": "carousel",
  "theme": "auto",
  "accent_color": "#0f766e",
  "fields": { "avatar": true, "name": true, "title": true, "company": true, "rating": true, "date": false },
  "attribution": true,
  "brand_name": "Northwind",
  "rating": { "average": 4.8, "count": 12 },
  "header": {
    "title": "What our customers say",
    "subtitle": "Real words from real customers.",
    "title_color": null,
    "text_color": null,
    "rating": { "average": 4.7, "count": 112 },
    "count": 112
  },
  "items": [
    {
      "kind": "video",
      "name": "Maria Garcia",
      "title": "Head of Operations",
      "company": "Northwind",
      "rating": 5,
      "date": null,
      "text": "It halved our onboarding time.",
      "video_url": "https://cdn.akteora.com/m/7kq2m9xwzr4tn8vbh3jp/video.mp4",
      "audio_url": null,
      "poster_url": "https://cdn.akteora.com/m/7kq2m9xwzr4tn8vbh3jp/poster.jpg",
      "duration_ms": 42000,
      "language": "en",
      "captions": [{ "start_ms": 0, "end_ms": 1800, "text": "It halved our onboarding time." }]
    }
  ]
}

What it promises: