Trigger measurement cycles and read visibility, trends, crawler activity and the individual answers behind them.
Paths on this page are relative to https://shruwd.io/api/v1.
| Method | Path | Scope | Role |
|---|---|---|---|
POST | /brands/{brandId}/cycles | write | editor |
GET | /brands/{brandId}/cycles | read | viewer |
GET | /brands/{brandId}/visibility | read | viewer |
GET | /brands/{brandId}/visibility/series | read | viewer |
GET | /brands/{brandId}/crawlers | read | viewer |
GET | /brands/{brandId}/answers | read | viewer |
Measurement is asynchronous. Running a cycle schedules work; results arrive over the following hours. Nothing you can call returns a finished measurement, so do not poll in a tight loop and do not report a number before there is one.
Run a cycle
curl -X POST "https://shruwd.io/api/v1/brands/waitlister/cycles" \
-H "Authorization: Bearer $SHRUWD_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Creates a manual cycle due now and returns its id. It draws on the same period allowance as any cycle.
On a free plan this is the one snapshot, and is 409 snapshot_taken once used. A
workspace paused pending review is 409 workspace_on_hold.
GET /brands/{brandId}/cycles?limit= returns recent cycles with their state and counts.
Read visibility
curl "https://shruwd.io/api/v1/brands/waitlister/visibility?engine=google_aio" \
-H "Authorization: Bearer $SHRUWD_API_KEY"
| Parameter | |
|---|---|
engine | google_aio or chatgpt |
from to | YYYY-MM-DD. to defaults to today in the brand's timezone |
Returns { engine, range, asOf, nResponses, entities, prompts }. Each entity carries
mentionRate, shareOfVoice and avgProminence, every one of them with its interval or
an explicit insufficient_data.
If from reaches past your plan's history window it is clamped, and the response says so
in historyFrom rather than failing.
Read the trend
curl "https://shruwd.io/api/v1/brands/waitlister/visibility/series?window=30" \
-H "Authorization: Bearer $SHRUWD_API_KEY"
| Parameter | |
|---|---|
window | 7, 30 or 90. Default 30 |
from to | Default is the last ninety days |
Returns points (one per cycle close) and, per entity, a series index-aligned with
it. A point below the display floor is insufficient_data, never a number.
modelChanges lists the moments the provider changed its underlying models. A difference
spanning one of those may be the model rather than you — see
When a number has moved.
Read crawler activity
curl "https://shruwd.io/api/v1/brands/waitlister/crawlers" \
-H "Authorization: Bearer $SHRUWD_API_KEY"
Per-bot activity with verified and unverified hits kept separate. Only verified hits count toward anything.
daily carries a per-day series per bot, index-aligned with daily.days.
A day with no log ingest is null, not 0. It means nobody was watching, not that
nothing happened — do not chart it as zero.
Read individual answers
curl "https://shruwd.io/api/v1/brands/waitlister/answers?limit=10" \
-H "Authorization: Bearer $SHRUWD_API_KEY"
limit is 1–50, default 10. Newest first, measured runs only.
Each answer carries prompt, engine, state, executedAt, whether you were
mentioned and at what rank, the surrounding context, the competitors named, and
the citations with isSelf marked.
This is evidence, not a metric. Never compute a rate from these rows — the sample is whatever the last few runs happened to be. It exists so you can read what an answer actually said, which is useful while a brand is still below the display floor.
Next steps
- Findings — the diagnosed causes behind these numbers
- Metric definitions — what each number counts

