Manage competitors and the exact aliases that count as a mention, plus the suggestions drawn from real answers.
An entity is your brand or a competitor, together with the aliases, domains, exclusions and context terms that decide what counts as a mention of it.
Paths on this page are relative to https://shruwd.io/api/v1.
| Method | Path | Scope | Role |
|---|---|---|---|
GET | /brands/{brandId}/entities | read | viewer |
POST | /brands/{brandId}/entities | write | editor |
PUT | /entities/{entityId} | write | editor |
DELETE | /entities/{entityId} | write | editor |
Matching is exact
Every alias is matched as an exact string on word boundaries. The API does not accept patterns or regular expressions, and there is no fuzzy matching anywhere.
A near-match that quietly counts the wrong brand corrupts every metric downstream and is close to impossible to detect later. The cost is that you supply the spellings.
Add a competitor
curl -X POST "https://shruwd.io/api/v1/brands/waitlister/entities" \
-H "Authorization: Bearer $SHRUWD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "LaunchList",
"aliases": [{ "alias": "LaunchList", "kind": "name", "caseSensitive": false }],
"domains": ["getlaunchlist.com"]
}'
| Field | Required | Notes |
|---|---|---|
name | Yes | The canonical name |
aliases | No | Defaults to one alias equal to name |
domains | No | Reduced to registrable domains |
exclusions | No | Phrases that must not count as a mention |
contextTerms | No | Required for short or common-word names — see below |
Competitors only. isSelf is not accepted; the self entity arrives with the brand.
Short and common-word names
A name of six characters or fewer, or one on the common-word list, is refused with
422 context_terms_required until you supply contextTerms. The entity is then stored
with requires_context set.
This is not a nicety to route around. Without context terms, "Arc" counts every ordinary use of the word as a competitor mention, and every share-of-voice number for the brand becomes wrong in a way nobody notices.
Your brand's own entity has the same rule: creating a brand with such a
name needs contextTerms too. An entity whose name needs them and has none reads back with
needsContextTerms: true; add them with PUT.
Errors
| Code | Status | |
|---|---|---|
context_terms_required | 422 | The name needs context terms. The reason is in the body |
domain_taken | 409 | Another entity of this brand already owns that domain |
invalid_alias · invalid_domain · invalid_name | 422 | Bad input |
Replace an entity
PUT takes the desired state — the full set of aliases, domains, exclusions and
context terms you want.
curl -X PUT "https://shruwd.io/api/v1/entities/$entityId" \
-H "Authorization: Bearer $SHRUWD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"LaunchList","aliases":[{"alias":"LaunchList","kind":"name"},{"alias":"Launch List","kind":"name"}],"domains":["getlaunchlist.com"]}'
The server diffs against what exists: rows you dropped are closed as of now, new ones are inserted, unchanged ones are left alone. Nothing is ever edited in place, because a measurement taken yesterday must still resolve against yesterday's aliases.
Remove an entity
curl -X DELETE "https://shruwd.io/api/v1/entities/$entityId" \
-H "Authorization: Bearer $SHRUWD_API_KEY"
Closes the entity as of now. It stops counting from the next cycle; past measurements keep it, and share of voice is recomputed against the remaining set.
The self entity is 409 self_entity — archive the brand instead.
Suggestions
Shruwd lists names that appeared in your answers but are not tracked.
| Method | Path | Scope |
|---|---|---|
GET | /brands/{brandId}/suggestions?state= | read |
POST | /suggestions/{suggestionId}/accept | write |
POST | /suggestions/{suggestionId}/dismiss | write |
Each carries the share of a prompt cluster's answers that named it, and a domain hint where the answers linked one.
Accept creates the competitor through the same path as POST …/entities — the same
exact-alias rule, the same context_terms_required check. Pass name, aliases,
domains, exclusions or contextTerms to override the draft; the domain hint is used
unless you give domains.
Dismiss quiets it for 90 days.
A suggestion that has already been decided is 409 suggestion_decided.
Next steps
- Measurement — reading mention rate and share of voice
- Competitors — the same thing in the dashboard

