Klantly Developers

API-referentie

Reviews

Reviews van klanten en de verzoeken om er een te schrijven. Lezen kan volledig; een review zelf aanmaken bewust niet — die hoort van de klant te komen.

Endpoints

Reviews opvragen

GET /api/v1/reviews

Een lijst van reviews, nieuwste eerst. Filter op status, bron, score, klant of wijzigingsdatum. Met filter[status]=published haal je op wat openbaar staat.

Scope
reviews.read — Reviews en reviewverzoeken lezen
Vereiste functie
reviews

Queryparameters

NaamTypeOmschrijving
limit integer Aantal resultaten per pagina. van 1 tot 100 · standaard: 50
cursor string De next_cursor of prev_cursor uit meta van het vorige antwoord.
sort string Sortering op created_at of updated_at; een min-teken ervoor is aflopend. een van: -reviewed_at, reviewed_at, -created_at, created_at, -updated_at, updated_at · standaard: -reviewed_at
filter[status] string Alleen reviews met deze status: published (openbaar) of hidden (verborgen). een van: published, hidden
filter[source] string Alleen reviews uit deze bron: request (via een reviewverzoek), manual (zelf ingevoerd), configurator of google. een van: request, manual, configurator, google
filter[rating] integer Alleen reviews met deze score (1 tot en met 5). van 1 tot 5
filter[customer_id] string (uuid) Alleen wat bij deze klant hoort.
filter[updated_since] string (date-time) Alleen wat sinds dit tijdstip is gewijzigd: ISO 8601 mét tijdzone, bijvoorbeeld 2026-09-14T10:15:00Z. Handig om te synchroniseren.

Voorbeeldverzoek

cURL
curl "https://app.klantly.com/api/v1/reviews?filter[status]=published&sort=-reviewed_at" \
  -H "Authorization: Bearer $KLANTLY_API_KEY"
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('GET', 'reviews', [
    'query' => [
        'filter[status]' => 'published',
        'sort' => '-reviewed_at',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/reviews?filter[status]=published&sort=-reviewed_at', {
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
  },
});

const { data } = await response.json();
Python
import os

import requests

response = requests.get(
    "https://app.klantly.com/api/v1/reviews",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
    params={
        "filter[status]": "published",
        "sort": "-reviewed_at"
    },
)
data = response.json()["data"]

Antwoord 200

Het antwoord is een lijst met cursorpaginering: data bevat de objecten, meta de paginering.

Voorbeeldantwoord
{
  "data": [
    {
      "object": "review",
      "id": "9d3f9c34-8d9e-4f01-9123-c4d5e6f7a8b3",
      "status": "published",
      "hidden_reason": null,
      "source": "request",
      "rating": 5,
      "comment": "Strakke veranda, netjes geplaatst en goed opgeruimd.",
      "author": {
        "name": "Jan de Vries",
        "city": "Utrecht"
      },
      "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
      "language": "nl",
      "is_verified": true,
      "consent_publish": true,
      "reply": null,
      "replied_at": null,
      "reviewed_at": null,
      "created_at": "2026-09-14T10:15:00Z",
      "updated_at": "2026-09-14T10:15:00Z"
    }
  ],
  "meta": {
    "limit": 50,
    "next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
    "prev_cursor": null
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Review ophalen

GET /api/v1/reviews/{review}

Eén review op id, met de score, de tekst, de schrijver en het antwoord van het bedrijf.

Scope
reviews.read — Reviews en reviewverzoeken lezen
Vereiste functie
reviews

Padparameters

NaamTypeOmschrijving
review verplicht string (uuid) De id (UUID) van de review.

Voorbeeldverzoek

cURL
curl "https://app.klantly.com/api/v1/reviews/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
  -H "Authorization: Bearer $KLANTLY_API_KEY"
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('GET', 'reviews/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/reviews/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
  },
});

const { data } = await response.json();
Python
import os

import requests

response = requests.get(
    "https://app.klantly.com/api/v1/reviews/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "review",
    "id": "9d3f9c34-8d9e-4f01-9123-c4d5e6f7a8b3",
    "status": "published",
    "hidden_reason": null,
    "source": "request",
    "rating": 5,
    "comment": "Strakke veranda, netjes geplaatst en goed opgeruimd.",
    "author": {
      "name": "Jan de Vries",
      "city": "Utrecht"
    },
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "language": "nl",
    "is_verified": true,
    "consent_publish": true,
    "reply": null,
    "replied_at": null,
    "reviewed_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Reviewverzoeken opvragen

GET /api/v1/review-requests

De verstuurde en openstaande reviewverzoeken, nieuwste eerst, met hun status en de link voor de klant.

Scope
reviews.read — Reviews en reviewverzoeken lezen
Vereiste functie
reviews

Queryparameters

NaamTypeOmschrijving
limit integer Aantal resultaten per pagina. van 1 tot 100 · standaard: 50
cursor string De next_cursor of prev_cursor uit meta van het vorige antwoord.
filter[status] string Alleen verzoeken met deze status: scheduled, sent, opened, completed, failed, cancelled of expired. een van: scheduled, sent, opened, completed, failed, cancelled, expired
filter[customer_id] string (uuid) Alleen wat bij deze klant hoort.
filter[updated_since] string (date-time) Alleen wat sinds dit tijdstip is gewijzigd: ISO 8601 mét tijdzone, bijvoorbeeld 2026-09-14T10:15:00Z. Handig om te synchroniseren.

Voorbeeldverzoek

cURL
curl "https://app.klantly.com/api/v1/review-requests" \
  -H "Authorization: Bearer $KLANTLY_API_KEY"
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('GET', 'review-requests');

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/review-requests', {
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
  },
});

const { data } = await response.json();
Python
import os

import requests

response = requests.get(
    "https://app.klantly.com/api/v1/review-requests",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
)
data = response.json()["data"]

Antwoord 200

Het antwoord is een lijst met cursorpaginering: data bevat de objecten, meta de paginering.

Voorbeeldantwoord
{
  "data": [
    {
      "object": "review_request",
      "id": "9d3f9d45-9e0f-4012-a234-d5e6f7a8b9c4",
      "status": "sent",
      "channel": "email",
      "trigger": "manual",
      "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
      "recipient": {
        "name": "Jan de Vries",
        "email": "jan@example.com",
        "phone": null
      },
      "language": "nl",
      "url": "https://app.klantly.com/review/Xk2p9Qm4Rt7vB1nC8dE5fG3hJ6kL0mN2pQ4rS7tU",
      "review_id": null,
      "scheduled_at": null,
      "sent_at": null,
      "opened_at": null,
      "completed_at": null,
      "created_at": "2026-09-14T10:15:00Z",
      "updated_at": "2026-09-14T10:15:00Z"
    }
  ],
  "meta": {
    "limit": 50,
    "next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
    "prev_cursor": null
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Reviewverzoek versturen

POST /api/v1/review-requests

Vraagt een klant om een review. Met channel=email of whatsapp stuurt Klantly het bericht met het sjabloon van het bedrijf; met channel=link maak je alleen de link aan en deel je hem zelf. Geef customer_id mee, of vul name plus email of phone in. Dezelfde regels als in het scherm: geen tweede openstaand verzoek aan dezelfde klant, de afkoelperiode van het bedrijf, en niemand die zich heeft afgemeld — anders volgt 409 conflict.

Scope
reviews.write — Reviewverzoeken naar klanten sturen (een review zelf aanmaken kan niet)
Vereiste functie
reviews

Stuur een Idempotency-Key mee, dan maakt een nieuwe poging na een time-out geen dubbel record.

Body (JSON)

VeldTypeOmschrijving
customer_id optioneel string (uuid) De klant die het verzoek krijgt.
name optioneel string Naam van de ontvanger. Nodig als je geen customer_id meegeeft. maximaal 120 tekens
email optioneel string (email) E-mailadres van de ontvanger. Nodig bij channel=email. maximaal 255 tekens
phone optioneel string Telefoonnummer van de ontvanger. Nodig bij channel=whatsapp. maximaal 50 tekens
channel optioneel string Hoe het verzoek bij de klant komt: email, whatsapp of link (dan verstuurt Klantly niets). een van: email, whatsapp, link
language optioneel string De taal van het bericht aan de klant. een van: nl, en, de, fr

Voorbeeldverzoek

cURL
curl -X POST "https://app.klantly.com/api/v1/review-requests" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
  -d '{
  "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
  "channel": "email"
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('POST', 'review-requests', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
    'json' => [
        'customer_id' => '9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70',
        'channel' => 'email',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/review-requests', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
  },
  body: JSON.stringify({
  "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
  "channel": "email"
}),
});

const { data } = await response.json();
Python
import os

import requests

response = requests.post(
    "https://app.klantly.com/api/v1/review-requests",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
        "Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    },
    json={
        "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
        "channel": "email"
    },
)
data = response.json()["data"]

Antwoord 201

Voorbeeldantwoord
{
  "data": {
    "object": "review_request",
    "id": "9d3f9d45-9e0f-4012-a234-d5e6f7a8b9c4",
    "status": "sent",
    "channel": "email",
    "trigger": "manual",
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "recipient": {
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": null
    },
    "language": "nl",
    "url": "https://app.klantly.com/review/Xk2p9Qm4Rt7vB1nC8dE5fG3hJ6kL0mN2pQ4rS7tU",
    "review_id": null,
    "scheduled_at": null,
    "sent_at": null,
    "opened_at": null,
    "completed_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Het object

Alle velden zijn altijd aanwezig; een veld zonder waarde is null.

VeldTypeOmschrijving
object string Altijd "review".
id string (uuid) Id van de review.
status string published (openbaar) of hidden (verborgen). een van: published, hidden
hidden_reason string Waarom de review verborgen is, als dat zo is. kan leeg zijn (null) · een van: spam, offensive, not_a_customer, privacy, duplicate, other
source string Waar de review vandaan komt: request, manual, configurator of google. een van: request, manual, configurator, google
rating integer De score, 1 tot en met 5. van 1 tot 5
comment string Wat de klant schreef. kan leeg zijn (null)
author object De schrijver, zoals hij openbaar getoond wordt.
author.name string Naam van de schrijver. kan leeg zijn (null)
author.city string Woonplaats van de schrijver. kan leeg zijn (null)
customer_id string (uuid) De klant die de review schreef, als die bekend is. kan leeg zijn (null)
language string De taal waarin de review is geschreven. kan leeg zijn (null) · een van: nl, en, de, fr
is_verified boolean True als de review via een reviewverzoek van Klantly is ingevuld: de schrijver is dan aantoonbaar klant.
consent_publish boolean Of de schrijver toestemming gaf om de review te tonen.
reply string Het antwoord van het bedrijf op deze review. kan leeg zijn (null)
replied_at string (date-time) Wanneer het bedrijf antwoordde. kan leeg zijn (null)
reviewed_at string (date-time) Wanneer de review is geschreven. kan leeg zijn (null)
created_at string (date-time) Wanneer de review in Klantly kwam.
updated_at string (date-time) Wanneer de review voor het laatst wijzigde.