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, and the domains and YouTube channels whose pages and videos count as its citations.

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.

An alias that starts with a capital letter does not match where the answer writes it all in lowercase ("a narrow arc" is not Arc), except inside code, where names are lowercase. caseSensitive is stricter: the whole alias must match exactly as written.

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/northwind/entities" \
  -H "Authorization: Bearer $SHRUWD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Planwell",
    "aliases": [{ "alias": "Planwell", "kind": "name", "caseSensitive": false }],
    "domains": ["planwell.io"]
  }'
FieldRequiredNotes
nameYesThe canonical name
aliasesNoDefaults to one alias equal to name. Up to 50
domainsNoReduced to registrable domains. Up to 20
channelsNoYouTube channels, as https://www.youtube.com/@name or @name. Up to 5
exclusionsNoPhrases that must not count as a mention. Up to 50
contextTermsNoRequired for short or common-word names — see below. Up to 50

Competitors only. isSelf is not accepted; the self entity arrives with the brand. A brand tracks up to 100 companies, its own included; past that, 409 entity_limit.

Short and common-word names

A name or alias of six characters or fewer, or one on the common-word list, is refused with 422 context_terms_required until you supply contextTerms; details.spelling says which. The entity is then stored with requires_context set, and its domains are added to the terms.

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.

YouTube channels

Answers cite videos as well as pages, and a video's address says only youtube.com. Name a company's channel and a cited video from it counts as that company's citation: for your brand, in your own citation rate and as "Cited your video" on an answer. Give the channel's address as YouTube shows it, https://www.youtube.com/@name, or the @name handle alone. A /channel/UC… address is accepted too, but it matches only videos whose channel YouTube reports the same way, and today that is the handle.

It counts from the answers measured after you name it. Answers already measured keep the credit they had, as they do when you add a domain.

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
channel_taken409Another entity of this brand already has that YouTube channel
invalid_alias · invalid_domain · invalid_channel · 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":"Planwell","aliases":[{"alias":"Planwell","kind":"name"},{"alias":"Plan Well","kind":"name"}],"domains":["planwell.io"],"channels":["https://www.youtube.com/@planwell"]}'

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.

YouTube channels are the one exception: leave channels out and they stay as they are; send [] to remove them.

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