Lees profieldata uit bluebarry via de Data API en synchroniseer die naar je eigen systemen, zoals een datawarehouse, een CRM of een eigen dashboard. bluebarry voegt de vele contactmomenten van één klant (een anonieme quizsessie, een later geïdentificeerd bezoek, een tweede apparaat) samen tot één identiteit. Deze handleiding laat zien hoe je authenticeert, die identiteiten uitleest en alleen ophaalt wat sinds je vorige run is veranderd, zonder records te missen of dubbel binnen te halen.
Voordat je begint
Je hebt een API-sleutel nodig. Maak er een in Studio onderIntegrations → Developer area → API keys management en kopieer de waarde. Een API-sleutel hoort bij één workspace en kan elk profiel in die workspace lezen. Behandel hem dus als geheim en roep de API alleen aan vanaf een beveiligde server, nooit vanuit code in je webshop of de browser.
Production https://data.bluebarry.ai/data
Staging https://staging.data.bluebarry.ai/dataAuthenticeren
Stuur je sleutel mee in de Authorization-header. Gebruik alleen de kale sleutelwaarde. Zet er geen Bearer-prefix voor: een Bearer-token gaat naar een andere inlogmethode en je request wordt dan afgewezen met een 401.
curl "https://data.bluebarry.ai/data/Identities?\$top=5" \
-H "Authorization: bb_your_api_key_here"Identities of Profiles
Er zijn twee verwante collecties. Gebruik Identities, tenzij je een specifieke reden hebt om dat niet te doen.
- Identities geeft één rij per klant, samengevoegd uit alle contactmomenten. Elke rij heeft een stabiele id die je kunt opslaan en gebruiken om te upserten, plus het vastgestelde e-mailadres, telefoonnummer, naam, quizantwoorden en aanbevelingen. Dit is de juiste bron om mensen naar een ander systeem te synchroniseren.
- Profiles geeft de ruwe, niet-samengevoegde rijen (één per sessie en gebruiker). Gebruik dit alleen als je echt de details per sessie nodig hebt. Dezelfde klant kan als meerdere Profiles-rijen voorkomen.
De vorm van een identiteit
Een geldige sleutel geeft HTTP 200 terug met een JSON-envelop. De identiteiten staan in de array value. Veldnamen zijn in camelCase. De quizantwoorden onder properties en de productkeuzes onder recommendations komen direct mee.
{
"@odata.context": "https://data.bluebarry.ai/data/$metadata#Identities",
"value": [
{
"id": "0193b8a1-7e2c-7a10-9f4d-2b6f3c8e1a55",
"email": "[email protected]",
"phoneNumber": null,
"firstName": "Alice",
"lastName": "A",
"userId": "34d33fe3-e88e-47cd-8b70-d0f978b5bd2a",
"createdDate": "2026-06-01T10:00:00Z",
"updatedDate": "2026-06-14T09:12:00Z",
"memberCount": 3,
"consentAccepted": true,
"mergedIntoId": null,
"properties": [
{ "name": "skill_level", "value": "beginner" }
],
"recommendations": [
{
"position": 1,
"title": "Starter Rope",
"url": "https://shop.example/rope",
"quizName": "Climbing Quiz",
"price": 49.99
}
]
}
]
}- id is stabiel. Sla hem op en upsert erop. Hij verandert niet als er nieuwe sessies of apparaten bij dezelfde klant komen.
- memberCount is het aantal ruwe contactmomenten dat in deze identiteit is samengevoegd.
- mergedIntoId is normaal null. Zie Samenvoegingen verwerken hieronder.
Velden kiezen, filteren en sorteren
Het endpoint accepteert de standaard OData-queryopties. URL-encodeer de waarden, dus een spatie wordt %20 en een plus wordt %2B.
- $select geeft alleen de velden terug die je noemt, bijvoorbeeld $select=id,email,updatedDate.
- $filter beperkt de rijen, bijvoorbeeld op updatedDate of een e-mailadres.
- $orderby sorteert de rijen. Zet dit altijd als je pagineert, want zonder is de volgorde niet gegarandeerd.
- $count=true voegt een veld @odata.count toe met het totaal.
Bij tijdstempels sluit gt de grenswaarde uit en neemt ge hem mee. Gebruik een ISO 8601-waarde in UTC, zoals 2026-06-01T10:10:00Z.
Door grote resultaten pagineren
Eén request geeft maximaal 5000 rijen terug. Gebruik $top voor een kleinere paginagrootte (1 tot 5000) en $skip om naar de volgende pagina te gaan, altijd samen met een stabiele $orderby. Een $top buiten het bereik 1 tot 5000 geeft HTTP 400. Laat je $top weg en is het resultaat groter dan 5000 rijen, dan bevat de response een URL in @odata.nextLink. Volg die tot hij er niet meer is.
Alleen wijzigingen synchroniseren, zonder records te missen
Elke identiteit heeft een updatedDate die vooruit schuift zodra de klant actief is. Voor een incrementele sync onthoud je de nieuwste updatedDate die je hebt verwerkt en vraag je bij de volgende run de identiteiten op die sindsdien zijn veranderd. Upsert elke identiteit in je systeem op basis van de id.
Eén ding om te weten: updatedDate wordt gezet op het moment dat een klantevent ontstaat, maar de wijziging wordt een moment later weggeschreven, en die schrijfacties komen niet gegarandeerd in volgorde van tijdstempel binnen. Een wijziging met een eerdere updatedDate kan dus zichtbaar worden nadat je dat tijdstip al voorbij bent. Filter je strikt op groter dan je laatste tijdstempel, dan kun je die missen. Voorkom dat met een kleine overlap: begin elke run iets vóór je laatste tijdstempel (bijvoorbeeld een uur) en lees de overlap opnieuw. Omdat je op id upsert, kan het geen kwaad een rij die je al hebt nog eens te lezen.
// cursor is de nieuwste updatedDate die je volledig hebt verwerkt.
let cursor = loadCursor() ?? "1970-01-01T00:00:00Z";
const OVERLAP_MS = 60 * 60 * 1000; // veiligheidsmarge van 1 uur
async function sync() {
const from = new Date(Date.parse(cursor) - OVERLAP_MS).toISOString();
let newest = cursor;
let skip = 0;
while (true) {
const url = new URL("https://data.bluebarry.ai/data/Identities");
url.searchParams.set("$filter", `updatedDate ge ${from}`);
url.searchParams.set("$orderby", "updatedDate asc,id asc");
url.searchParams.set("$top", "1000");
url.searchParams.set("$skip", String(skip));
const res = await fetch(url, {
headers: { Authorization: process.env.BLUEBARRY_API_KEY },
});
const { value } = await res.json();
if (value.length === 0) break;
for (const identity of value) {
if (identity.mergedIntoId) {
// Deze identiteit is samengevoegd met een andere; voeg je lokale kopie samen met mergedIntoId.
redirect(identity.id, identity.mergedIntoId);
} else {
upsertById(identity.id, identity); // idempotent: opnieuw lezen kan geen kwaad
}
if (identity.updatedDate > newest) newest = identity.updatedDate;
}
skip += value.length;
}
saveCursor(newest); // pas verder zetten als de hele run is gelukt
}Zet de cursor pas verder en sla hem op als een run helemaal is gelukt. Mislukt een run halverwege, dan begint de volgende run bij de oude cursor en vangt de overlap alles daartussen op.
Samenvoegingen verwerken
Soms blijken twee identiteiten dezelfde klant te zijn. Bijvoorbeeld als een anonieme bezoeker later een e-mailadres opgeeft dat al bij een andere identiteit hoorde. bluebarry houdt dan één identiteit over en markeert de andere met een mergedIntoId die naar de overgebleven identiteit wijst. De opgeheven identiteit verschijnt nog wel in de wijzigingen, zodat je sync je lokale kopie van de oude id kan samenvoegen met de overgebleven identiteit. Filter met mergedIntoId eq null als je alleen actieve identiteiten wilt.
Limieten en goede gewoontes
- Vraag maximaal 5000 rijen per aanroep op en pagineer door de rest.
- Gebruik $select om alleen de velden op te halen die je nodig hebt. Zo blijven responses klein en snel.
- Identiteiten bevatten persoonsgegevens zoals e-mailadres, telefoonnummer en naam. Sla ze op en verwerk ze volgens je privacyverplichtingen, en respecteer de vlag consentAccepted.
- Houd je API-sleutel op de server. Is een sleutel uitgelekt, verwijder hem dan in Studio en maak een nieuwe.