Build on Shruwd

Entities API

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.

MethodPathScopeRole
GET/brands/{brandId}/entitiesreadviewer
POST/brands/{brandId}/entitieswriteeditor
PUT/entities/{entityId}writeeditor
DELETE/entities/{entityId}writeeditor

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"]
  }'
FieldRequiredNotes
nameYesThe canonical name
aliasesNoDefaults to one alias equal to name
domainsNoReduced to registrable domains
exclusionsNoPhrases that must not count as a mention
contextTermsNoRequired 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

CodeStatus
context_terms_required422The name needs context terms. The reason is in the body
domain_taken409Another entity of this brand already owns that domain
invalid_alias · invalid_domain · invalid_name422Bad 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.

MethodPathScope
GET/brands/{brandId}/suggestions?state=read
POST/suggestions/{suggestionId}/acceptwrite
POST/suggestions/{suggestionId}/dismisswrite

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