Skip to Content
APIEndpointsCreate competitor

Create competitor

Adds a competitor to the set this brand is tracked against. The new competitor is matched against future answers by its name, its aliases and its domain, and appears in List competitors and the rankings immediately.

Creates the same row the Add competitor dialog does, including its defaults: active, manually added, a direct competitor, and matched on the whole registrable domain.

Requires the write:competitors scope, and the workspace must be enabled for API writes.

POST /v1/brands/{brand_id}/competitors

Authorization

HeaderTypeRequired
AuthorizationBearer asky_sk_…required
Idempotency-Keystringrequired

Path parameters

ParameterTypeRequiredDescription
brand_iduuidrequiredFrom List brands

Query parameters

None.

Any parameter you pass returns 400 invalid_request naming the offending key.

Body

application/json

FieldTypeRequiredDescription
namestring, 1–200 charsrequiredDisplay name, also matched against answers
primary_urlstring, up to 2048 charsrequiredThe competitor’s main URL, http or https, pointing at a domain
aliasesstring[], up to 50optionalOther names to match on. Blanks and duplicates are dropped. Defaults to []
relationstringoptionalOne of direct_competitor, indirect_competitor, partner. Defaults to direct_competitor
match_case_sensitivebooleanoptionalMatch name and aliases case-sensitively. Defaults to false
match_require_domainbooleanoptionalOnly count a page mention when a domain signal is present. Defaults to false

Request

curl --request POST \ --url 'https://api.askylabs.com/v1/brands/242546de-4cee-4a7d-952e-f6aa60c63ef8/competitors' \ --header 'Authorization: Bearer <api-key>' \ --header 'Idempotency-Key: <unique-per-attempt>' \ --header 'Content-Type: application/json' \ --data '{"name":"Profound","primary_url":"https://tryprofound.com","aliases":["Try Profound"]}'

Response

{ "data": { "competitor": { "id": "c4a7e1b2-38d9-4f60-b5ac-2d90e7f14b83", "name": "Profound", "primary_url": "https://tryprofound.com", "domain": "tryprofound.com", "relation": "direct_competitor", "aliases": ["Try Profound"], "is_active": true, "is_manual": true, "match_case_sensitive": false, "match_require_domain": false, "match_mode": "apex" } }, "request_id": "req_9e14c0bd72a34f81b5de" }

Response fields

FieldTypeDescription
data.competitor.iduuidrequired. Use it with Get competitor or as a competitor_id filter
data.competitor.namestringrequired
data.competitor.primary_urlstring | nullrequired
data.competitor.domainstring | nullrequired. Derived from primary_url. See the note below on when it is null
data.competitor.relationstringrequired
data.competitor.aliasesstring[]required
data.competitor.is_activebooleanrequired
data.competitor.is_manualbooleanrequired. Always true for competitors created here
data.competitor.match_case_sensitivebooleanrequired
data.competitor.match_require_domainbooleanrequired
data.competitor.match_modestringrequired. Always apex for competitors created here
request_idstringrequired. Also returned as the x-request-id header

Errors

StatusCodeWhen
400invalid_requestUnknown field, missing name or primary_url, a URL that is not http/https or does not point at a domain, an unknown relation, or more than 50 aliases
401invalid_tokenThe key is missing, malformed, or does not exist
403insufficient_scopeThe key does not carry write:competitors
403plan_requiredThis workspace is not enabled for API writes
404not_foundThe brand does not exist, or this key is not allowed to reach it
429rate_limitedOver 60 requests per minute

Notes

primary_url is required, unlike in the read shape. A competitor added by hand must have a URL: it is how citations and page mentions are attributed. Only auto-discovered competitors may exist without one.

domain can come back null, and that is not an error. It is derived from primary_url, and if another competitor on this brand already claims the same domain, the field is left empty rather than the request failing. Matching still works, because the domain is derived from primary_url when answers are scored. A null here is the signal that you may be tracking the same company twice.

Names are not unique. Two competitors on one brand may share a name. If you are syncing from an external system, deduplicate on domain rather than on name.

Some fields are deliberately not settable. regex_pattern, extra_apex_domains, owned_url_scopes and match_mode all change how citations are attributed, retroactively across all history, so they are not part of creating a competitor. Set them in the app.

Idempotency-Key is required. Reuse it when retrying an attempt and the original response is replayed rather than a second competitor being created. See Idempotency.

Last updated on