Delete competitor
Permanently removes a competitor and every measurement ever recorded against it. This is the most destructive call on the API. Read the warning below before using it.
Run it with ?dry_run=true first. That returns exactly what would be removed and removes nothing.
Requires the write:competitors scope, and the workspace must be enabled for API writes.
DELETE /v1/brands/{brand_id}/competitors/{competitor_id}Authorization
| Header | Type | Required |
|---|---|---|
Authorization | Bearer asky_sk_… | required |
Idempotency-Key | string | required |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
brand_id | uuid | required | From List brands |
competitor_id | uuid | required | From List competitors |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
dry_run | boolean | optional | Report what would be deleted and delete nothing. Defaults to false |
Request
cURL
# Always look first.
curl --request DELETE \
--url 'https://api.askylabs.com/v1/brands/242546de-4cee-4a7d-952e-f6aa60c63ef8/competitors/c4a7e1b2-38d9-4f60-b5ac-2d90e7f14b83?dry_run=true' \
--header 'Authorization: Bearer <api-key>' \
--header 'Idempotency-Key: <unique-per-attempt>'Response
200 dry run
{
"data": {
"dry_run": true,
"deleted": false,
"competitor": {
"id": "c4a7e1b2-38d9-4f60-b5ac-2d90e7f14b83",
"name": "Semrush",
"primary_url": "https://semrush.com",
"domain": "semrush.com",
"relation": "direct_competitor",
"aliases": [],
"is_active": true,
"is_manual": true,
"match_case_sensitive": false,
"match_require_domain": false,
"match_mode": "apex"
},
"would_delete": {
"executions": 19861,
"prompt_analytics": 10734,
"topic_analytics": 3445,
"brand_analytics": 273,
"domain_candidates": 0,
"tag_assignments": 0,
"total_rows": 34313
}
},
"request_id": "req_5a1f0c8e37b14d92a6be"
}Response fields
| Field | Type | Description |
|---|---|---|
data.dry_run | boolean | required. Echoes what you asked for |
data.deleted | boolean | required. false on a dry run |
data.competitor | object | required. The competitor, as Get competitor returns it. Captured before deletion |
data.would_delete | object | present on a dry run only |
data.removed | object | present on a real delete only |
….executions | integer | required. Per-execution mention records |
….prompt_analytics | integer | required. Per-prompt rollups |
….topic_analytics | integer | required. Per-topic rollups |
….brand_analytics | integer | required. Per-brand rollups |
….domain_candidates | integer | required. Discovered domains for this competitor |
….tag_assignments | integer | required. Tag links, the only cheap one to rebuild |
….total_rows | integer | required. The sum, and the number worth reading |
request_id | string | required. Also returned as the x-request-id header |
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_request | dry_run is not a boolean, or an unknown query parameter was sent |
| 401 | invalid_token | The key is missing, malformed, or does not exist |
| 403 | insufficient_scope | The key does not carry write:competitors |
| 403 | plan_required | This workspace is not enabled for API writes |
| 404 | not_found | The brand or competitor does not exist, or this key is not allowed to reach it |
| 429 | rate_limited | Over 60 requests per minute |
Notes
This is not reversible and there is no soft delete. The competitor row and every cascading measurement are gone. There is no undo, no trash, and no export beforehand. On real data this is routinely tens of thousands of rows: a well-established competitor on an active brand carried 34,313 when we measured it.
It changes numbers you did not ask it to change. Share of voice is relative, so removing one competitor alters every remaining competitor’s historical share on that brand. Charts you have already looked at, screenshotted or reported will not match afterwards. This is the part people do not expect, and it is the main reason to prefer deactivating.
Deactivating is almost always what you want. PATCH with is_active: false
(Update competitor) stops tracking the competitor from the next
run onward and keeps every historical number intact and comparable. Use delete only when the
competitor was genuinely a mistake, such as a duplicate or a typo, and its history is noise you
want gone.
Idempotency-Key is required, including on dry runs. Reuse it when retrying an attempt and the
original response is replayed rather than the delete running twice. See
Idempotency.