← ThinkAloud · API-nøgler (profil) · English · Dansk
ThinkAloud er API-first: UI'et bruger præcis de samme endpoints som beskrevet her. Tiltænkt server-til-server-integration (fx web-tracking.eu som add-on: måling finder siden med høj exit-rate + søgeordet — ThinkAloud simulerer *hvorfor* de smutter). Ingen CORS er åbnet med vilje: kald fra jeres backend, ikke fra browseren.
Base-URL: https://thinkaloud.activero.net (pilot; én maskine — kør én test ad gangen).
Auth — to måder:
Authorization: Bearer ta_... — oprettes på /app/profile → "API keys" (vises kun én gang; op til 10 aktive, tilbagekald enkeltvis). Nøglen giver konto-kontekst: kørsler tilskrives kontoen, credits trækkes, og GET /api/runs viser kun kontoens egne kørsler.X-Access-Code: <koden>. Serverens THINKALOUD_ACCESS_CODE er en komma-separeret liste — giv hver integration sin egen kode, så den kan tilbagekaldes uafhængigt. Uden konto-kontekst (ingen kreditering/ejerskab).Læse-endpoints kræver ét af: signeret ?t=-token (fra status/list-svar), ejerskab, eller adgangskode. 401-detail er altid "access_denied".
POST /api/runs
Content-Type: application/json
X-Access-Code: <koden>
{
"url": "https://example.com/side",
"goal": "Forstå hvad siden tilbyder, og om det er relevant for dig.",
"contentType": "dissemination", // conversion | dissemination | reference
"mode": "thinkaloud", // thinkaloud (UX) | e2e (funktionalitetstest)
"lang": "da", // output-sprog for personaer + rapport (da | en)
"model": "glm", // komma-sep.: glm (default, billigst),gemini,claude,llama,mistral (EU),grok (premium)
"steps": 8, // trin pr. persona (e2e: brug 15)
"synthesisModel": "grok", // valgfri premium-pen: SKRIVER anbefalinger/syntese
// (personaerne beholder deres egen model).
// Udførlig (comprehensive) bruger grok automatisk.
"personas": [
{"id": "sogende", "label": "Søgende med konkret intention",
"role": "Du googlede '<søgeord fra GSC>' og landede her. Du er utålmodig...",
"style": "maalrettet"} // valgfri: metodisk | rodet | maalrettet
]
}
→ {"run_id": "20260722-091653-f5fc0f"}
Til GSC-integrationen: byg personaens role af det rigtige søgeord ("Du googlede X …") i stedet for en opfundet profil — det er hele pointen.
Tre valgfrie felter i samme POST /api/runs-body åbner sider bag en gate — KUN testkonti (personaerne klikker rigtigt rundt, inkl. destruktive knapper):
{
"auth": {"user": "test", "password": "..."}, // HTTP Basic (staging-gates)
"headers": {"X-Api-Key": "..."}, // vilkårlige headers, fx nøgle-gatet site
"storage_state": "{\"cookies\": [...]}" // session-injektion: log selv ind, eksportér
} // sessionen (Playwright storageState ELLER
// Cookie-Editor-array) → SSO/2FA uden password
Sikkerhed: secrets gives kun til browser-harnessen via ephemere env-variabler — config.json på serveren beholder redigerede pladsholdere (***), og de optræder aldrig i rapport/log. Form-login med testkonto virker også uden felterne: skriv kontoen ind i goal ("log ind som test@… / kode …"), så udfører personaen selv login-formularen.
GET /api/runs/{run_id}
→ {"run_id": ..., "status": "running|done|error", "log": "<tail>",
"progress": {"phase": "reading", "pct": 42, "text": "Persona · Model", ...}}
Poll hvert 10-15 s. En kørsel tager typisk 1-5 min (flere personaer/modeller = længere; pr.-side-forankring koster ~25 s pr. ny unik side personaerne besøger).
GET /api/runs/{run_id}/results ← maskinlæsbart (integration)
GET /api/runs/{run_id}/report ← HTML-rapport (menneske; deling: linket er åbent)
GET /api/runs/{run_id}/report.pdf ← PDF
/results (kun ved status: "done"):
{
"run_id": "...", "status": "done",
"url": "...", "contentType": "...", "goal": "...", "mode": "thinkaloud", "lang": "da",
"firstGlancePriming": true, // personaernes første indtryk var saliency-forankret
"modelsUsed": ["Gemini-2.5"],
"personas": [{"label": "...", "model": "Gemini-2.5", "endedBy": "done"}],
"outcomes": [ /* e2e-mode: {label, model, succeeded, endedBy, steps, blocker, url, step} */ ],
"issues": [{"title": "...", "field": "tryghed|mening|kan|besvaer|defekt",
"summary": "...", "nPersonas": 2, "avgSev": 3.5, "models": ["Gemini-2.5"],
"pts": [{"label": "...", "model": "...", "url": "...", "what": "...",
"severity": 4, "step": 3}]}],
"positives": [ /* samme form, severity 0 */ ],
"attention": {"model": "deepgaze-iie", "on_action_total": 0.21, "off_action": 0.79,
"elements": [{"name": "...", "kind": "handling|overskrift|billede",
"share": 0.17, "primary": true}]}
}
Tolkning: issues er sorteret værst-først (flest personaer → flest modeller → højest snit- severity). nPersonas >= 2 = konvergent. Alt er prædiktion, ikke måling — mærk det sådan i jeres UI. Valideringssløjfen: sammenlign prædikteret friktion med den faktiske exit-rate.
POST /api/panel {brief|candidates, ...} → fokusgruppe (synkron, 1-3 min; ~25 credits).
model default = "claude,glm": varianstest
2026-08-24 viste at ét-models-paneler kan
flippe vinderen mellem kørsler — to modeller
gav samme dom i 3/3 genkørsler
POST /api/suggest-personas {url, goal?, lang?} → foreslå personaer ud fra siden (gated)
GET /sample → statisk eksempel-rapport (åben)
GET /api/defaults?lang=en → default-personaer + {"gated": true}
GET /api/keys · POST /api/keys · DELETE /api/keys/{id} → API-nøgle-administration
(kræver login-session, IKKE nøgle/kode)
GET /api/auth/me → konto + credit-saldo (virker m. Bearer)
npm-pakken thinkaloud-mcp eksponerer det hele som værktøjer i Claude Desktop/Code m.fl. — thinkaloud_start_test, thinkaloud_test_status, thinkaloud_test_results, thinkaloud_list_tests, thinkaloud_focus_group, thinkaloud_suggest_personas, thinkaloud_account. Én linje i Claude Code:
claude mcp add thinkaloud -e THINKALOUD_API_KEY=ta_DIN_NOEGLE -- npx -y thinkaloud-mcp
Auth via THINKALOUD_API_KEY (Bearer-nøglen ovenfor). Kildekoden ligger i mcp/ i repoet.