Create and manage brands — the domain and the prompts, competitors and findings attached to it.
Paths on this page are relative to https://shruwd.io/api/v1.
| Method | Path | Scope | Role |
|---|---|---|---|
POST | /brands | write | owner |
GET | /brands | read | viewer |
GET | /brands/{brandId} | read | viewer |
PATCH | /brands/{brandId} | write | editor |
DELETE | /brands/{brandId} | write | owner |
{brandId} accepts the brand's id or its slug.
Create a brand
curl -X POST "https://shruwd.io/api/v1/brands" \
-H "Authorization: Bearer $SHRUWD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Waitlister","domain":"waitlister.me","timezone":"Europe/Helsinki"}'
| Field | Required | Notes |
|---|---|---|
name | Yes | How the brand is written in answers. Becomes its first matching alias |
domain | Yes | A URL or a bare host. Reduced to the registrable domain |
timezone | No | Sets the day boundary for measurements |
contextTerms | For short or common-word names | Words that mark a mention as being about you. See below |
https://www.acme.com/pricing and acme.com resolve to the same brand. An IP address or
a string with no public suffix is 422 invalid_domain.
A short or common-word name, like "Front" or "Arc", is refused with
422 context_terms_required until you send contextTerms — for Front, say
["shared inbox", "customer support"]. A mention then counts only when one of those words
is near it; without them every "front-end" would count as a mention of you. The same rule
applies to competitors (Entities).
Creating a brand also:
- Creates its self entity, with the brand name as one alias and the domain attached. Nothing else can create one, and it cannot be removed.
- Plants the first cycle. The response carries
firstCycleas{ cycleId, kind, scheduledFor }, ornull. - Waits for prompts. A cycle with no active prompts stays pending, so creating a brand before its prompts costs nothing. Measurement starts within minutes of the first prompts and covers only the prompts and competitors that exist then, so add competitors first and every prompt in one call.
On the free plan the response also carries snapshot:
| Value | Meaning |
|---|---|
planned | Your one measurement for this domain is scheduled |
already_taken | This domain has had its free measurement, in some workspace. The brand exists; no cycle is planned |
null | You are not on a snapshot plan |
Errors
| Code | Status | |
|---|---|---|
invalid_domain · invalid_name · invalid_timezone | 422 | Bad input |
context_terms_required | 422 | The name is short or a common word. Send contextTerms; the reason is in the body |
duplicate_domain | 409 | An unarchived brand here already has that domain. details names it — { domain, brandId, slug, name } |
plan_limit | 409 | Your plan's brand count is used up. details carries { limit, current, resource } |
Another workspace tracking the same domain is not a conflict.
List brands
curl "https://shruwd.io/api/v1/brands" \
-H "Authorization: Bearer $SHRUWD_API_KEY"
Each brand carries a stats block — open findings, the last completed and next pending
cycle, the 30-day self mention rate per entitled engine, and a 56-day daily trend for the
primary engine. Days below the display floor are null rather than a number.
These come from rollups, so the list is cheap to poll compared with computing anything yourself from individual answers.
Get one brand
Returns the brand, its entitled engines, prompt and entity counts, and the same health block the dashboard shows — including the status of its Search Console connection and its log drain.
Update a brand
curl -X PATCH "https://shruwd.io/api/v1/brands/waitlister" \
-H "Authorization: Bearer $SHRUWD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Waitlister HQ"}'
Only name and timezone. Both optional, at least one required — 400 empty_patch
otherwise.
The domain is not editable. It defines the brand's self entity, so a different domain
is a different brand. The name here is display only; what Shruwd actually matches on
lives in the brand's aliases — see Entities.
A timezone change applies from the next cycle. The slug is stable across renames.
Archive a brand
curl -X DELETE "https://shruwd.io/api/v1/brands/waitlister" \
-H "Authorization: Bearer $SHRUWD_API_KEY"
Archives; nothing is deleted. Cycles stop being scheduled, history stays readable, and the domain becomes available to add again.

