How to use Glimt — from the dashboard UI and from the command line.
Glimt runs simulated users against your website and reports on what they struggled with. Each simulated user is a persona — a profile with distinct patience, trust requirements, and browsing habits. The agent navigates your site autonomously using an AI decision loop, then produces a scored report with friction points and recommendations.
You can trigger test runs from the dashboard UI or programmatically via the REST API using an API key.
Go to New Test in the sidebar. Fill in:
Click Run test. The run is queued immediately and you are redirected to the run status page, which auto-refreshes until the run completes.
Each persona simulates a different type of user. They differ in patience, trust requirements, price sensitivity, comprehension level, and device type. See the persona reference below for details.
To test pages that require a login, go to Saved Logins and click Record login. Enter a name and the login URL. A controlled browser will open — log in using a dedicated test account, then click I’m logged in →. The session is saved and can be selected when creating test runs.
Once a run completes, open it from the dashboard and click View report. The report shows:
The Glimt REST API lets you trigger runs from CI pipelines, scripts, or any HTTP client. The base URL is your deployment origin, e.g. https://your-app.railway.app.
Generate an API key under Settings → API Keys. Pass it in every request as a Bearer token:
Authorization: Bearer glmt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
API keys are SHA-256 hashed before storage. Keep the raw key safe — it is shown only once.
/api/v1/runscurl -X POST https://your-app.railway.app/api/v1/runs \
-H "Authorization: Bearer glmt_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yoursite.com",
"goal": "Find pricing and sign up for a free trial",
"sessions": ["alex", "margaret", "zoe"]
}'Request body:
{
"url": string, // required — must be a valid URL
"goal": string, // required — min 5 characters
"sessions": PersonaPreset[], // required — 1–10 items, duplicates allowed
"storageState"?: object|array // optional — Playwright state or Cookie-Editor export
}Response 201:
{ "testRunId": "clxxxxxxxxxxx" }/api/v1/runscurl https://your-app.railway.app/api/v1/runs \ -H "Authorization: Bearer glmt_xxx"
Response 200:
{
"runs": [
{
"id": "clxxx",
"url": "https://yoursite.com",
"goal": "Find pricing...",
"status": "COMPLETED", // QUEUED | RUNNING | COMPLETED | FAILED
"personaPresets": ["alex"],
"sessionCount": 1,
"queuedAt": "2026-04-07T10:00:00.000Z",
"completedAt": "2026-04-07T10:05:00.000Z",
...
}
]
}/api/v1/runs/:runIdReturns the full run including all sessions and their events. Useful for programmatic report parsing.
curl https://your-app.railway.app/api/v1/runs/clxxx \ -H "Authorization: Bearer glmt_xxx"
/api/v1/runs/:runId/statusLightweight endpoint for polling — returns status and session progress without the full event payload.
curl https://your-app.railway.app/api/v1/runs/clxxx/status \ -H "Authorization: Bearer glmt_xxx"
Response 200:
{
"runId": "clxxx",
"status": "RUNNING",
"completedSessions": 1,
"totalSessions": 3,
"startedAt": "2026-04-07T10:00:05.000Z"
}/api/v1/sessions/:sessionIdReturns a single session with all its step events (perception snapshots, actions, scores, think-aloud commentary).
curl https://your-app.railway.app/api/v1/sessions/clxxx \ -H "Authorization: Bearer glmt_xxx"
/api/v1/runs/:runId/cancelSends a cancel signal to the worker. The current session finishes its step, then the run stops. Only works when status is QUEUED or RUNNING.
curl -X POST https://your-app.railway.app/api/v1/runs/clxxx/cancel \ -H "Authorization: Bearer glmt_xxx"
Response 200:
{ "ok": true }Glimt has no dedicated CLI binary — you use standard tools like curl or httpie with your API key. Here are common patterns.
#!/bin/bash
API="https://your-app.railway.app/api/v1"
KEY="glmt_xxx"
# Create run
RUN_ID=$(curl -s -X POST "$API/runs" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://yoursite.com","goal":"Find pricing","sessions":["alex","zoe"]}' \
| jq -r '.testRunId')
echo "Run queued: $RUN_ID"
# Poll until done
while true; do
STATUS=$(curl -s "$API/runs/$RUN_ID/status" \
-H "Authorization: Bearer $KEY" | jq -r '.status')
echo "Status: $STATUS"
if [[ "$STATUS" == "COMPLETED" || "$STATUS" == "FAILED" ]]; then
break
fi
sleep 10
done
echo "Done — view at https://your-app.railway.app/dashboard/runs/$RUN_ID"# .github/workflows/ux-test.yml
name: UX test
on:
push:
branches: [main]
jobs:
useglimt:
runs-on: ubuntu-latest
steps:
- name: Create run
id: create
run: |
RUN_ID=$(curl -s -X POST "${{ vars.GLIMT_URL }}/api/v1/runs" \
-H "Authorization: Bearer ${{ secrets.GLIMT_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"url":"${{ vars.SITE_URL }}","goal":"Sign up","sessions":["alex","margaret"]}' \
| jq -r '.testRunId')
echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
- name: Wait for completion
run: |
for i in $(seq 1 30); do
STATUS=$(curl -s "${{ vars.GLIMT_URL }}/api/v1/runs/${{ steps.create.outputs.run_id }}/status" \
-H "Authorization: Bearer ${{ secrets.GLIMT_API_KEY }}" | jq -r '.status')
echo "Status: $STATUS"
[[ "$STATUS" == "COMPLETED" || "$STATUS" == "FAILED" ]] && break
sleep 20
doneconst BASE = "https://your-app.railway.app/api/v1";
const KEY = process.env.GLIMT_API_KEY;
const headers = {
"Authorization": `Bearer ${KEY}`,
"Content-Type": "application/json",
};
// Create run
const { testRunId } = await fetch(`${BASE}/runs`, {
method: "POST",
headers,
body: JSON.stringify({
url: "https://yoursite.com",
goal: "Find pricing and sign up",
sessions: ["alex", "carlos", "margaret"],
}),
}).then(r => r.json());
// Poll for completion
let status = "QUEUED";
while (status === "QUEUED" || status === "RUNNING") {
await new Promise(r => setTimeout(r, 10_000));
({ status } = await fetch(`${BASE}/runs/${testRunId}/status`, { headers })
.then(r => r.json()));
console.log("Status:", status);
}
console.log("Report:", `https://your-app.railway.app/dashboard/runs/${testRunId}`);The sessions field accepts an array of preset names. Each entry creates one simulated user session.
| Preset | Profile | Device | Key traits |
|---|---|---|---|
alex | 30-year-old developer | Desktop | Fast, low trust bar, skims content, acts immediately |
margaret | 58-year-old retired teacher | Desktop | Reads carefully, high trust & risk bar, needs clear value |
carlos | 35-year-old non-native speaker | Desktop | Thorough scroller, moderate trust, relies on structure not words |
david | 42-year-old project manager | Desktop | Practical, average comprehension, goal-driven, moderate patience |
zoe | 22-year-old Gen Z | Mobile | Scans only, ultra-low patience, expects instant clarity |
You can include the same persona multiple times — each will run as an independent session with a different random seed, producing varied but comparable results.