Signal API
Competitors as MarkdownUse a clean Markdown version of this page with an agent or local tooling.

Competitors

Manage tracked and suggested competitors for a project or location, including merges, bulk dismissal, and brand claims.

Domains are normalized before comparison. A tracked competitor requires a domain and cannot use the primary brand domain. Competitor analytics are documented in the Visibility group. Reading requires competitors:read; mutations require competitors:write.
GET
/projects/{project_id}/competitors?state=tracked

Returns tracked competitors for the selected project, together with the primary brand and pagination.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
Parameters

Query parameters

statetracked | suggested

Return competitors in one lifecycle state.

OptionalDefault: tracked
qstring

Case-insensitive search across name, domain, and aliases.

Optional
domainall | with-domain | without-domain

Return all competitors or filter by whether a domain is present.

OptionalDefault: all
sortname-asc | name-desc | newest | visibility | mentions

Sort by name, creation time, visibility rate, or mention count.

OptionalDefault: name-asc
pageinteger

The 1-based page number.

OptionalDefault: 1
per_pageinteger

Number of competitors per page. Minimum: 1. Maximum: 50; this matches the maximum suggested dataset size.

OptionalDefault: 25
Response

List response envelope

project_id:uuidprimary:Competitorcompetitors:Competitor[]pagination:Pagination
project_iduuid

Resolved Ceyo project identifier.

primaryCompetitor

Primary tracked brand for comparison.

competitorsCompetitor[]

Competitors matching the filters.

paginationPagination

Pagination metadata for competitors.

Object

Competitor

iduuid

Unique competitor identifier.

kindprimary | competitor

Entity role. Items in competitors are competitor; primary describes the tracked brand.

namestring

Display name used in prompts, results, and reports.

domainstring | null

Normalized hostname without a scheme, path, query, leading www, or trailing dot.

aliasesstring[]

Additional names recognized as this entity. Maximum: 10.

statusactive | inactive

Processing status. Competitors are active exactly when tracked and inactive when suggested or dismissed.

competitor_statetracked | suggested | dismissed | null

Competitor management lifecycle state. Null for the primary brand.

created_atdatetime

Competitor creation time.

updated_atdatetime

Last competitor update time.

Object

Pagination

pageinteger

Current 1-based page number.

per_pageinteger

Requested page size. Minimum: 1. Maximum: 50.

totalinteger

Total competitors matching the applied filters.

total_pagesinteger

Total pages at the current per_page value.

Request and response

Example requestcURL
curl --request GET \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors?state=tracked&sort=visibility&domain=all&page=1&per_page=25' \
  --header 'Authorization: Bearer ceyo_platform_...'
Example responseJSON
{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "primary": {
    "id": "10cf756e-ad42-43d7-beda-e8e9cc96cd41",
    "kind": "primary",
    "name": "Acme",
    "domain": "acme.example",
    "aliases": ["Acme AI"],
    "status": "active",
    "competitor_state": null,
    "created_at": "2026-04-12T08:00:00Z",
    "updated_at": "2026-07-28T10:30:00Z"
  },
  "competitors": [
    {
      "id": "63ec8dad-c12f-43c8-89e4-06eb629d0977",
      "kind": "competitor",
      "name": "Northstar",
      "domain": "northstar.example",
      "aliases": ["Northstar AI"],
      "status": "active",
      "competitor_state": "tracked",
      "created_at": "2026-07-02T11:20:00Z",
      "updated_at": "2026-07-30T09:10:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "total_pages": 1
  }
}
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

422invalid_filter | validation_failed

A state, sort, or domain filter is invalid, or a pagination value is outside the supported range.

429rate_limit_exceeded

Too many requests were made.

POST
/projects/{project_id}/competitors

Creates a tracked competitor and returns 201 Created. If the normalized domain or case-insensitive name matches an existing dismissed competitor, that record is reactivated and returned with 200 OK instead of creating a duplicate. A tracked competitor requires a domain; aliases accept at most 10 unique values.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
Request

Request body

namestring

Competitor display name. Required.

domainstring

Competitor domain. Required for a tracked competitor and normalized before matching.

aliasesstring[]

Optional alternate names. Maximum: 10 unique values.

Response

Create competitor response envelope

project_id:uuidcompetitor:Competitor
project_iduuid

Resolved Ceyo project identifier.

competitorCompetitor

Created or updated competitor.

Object

Competitor

iduuid

Unique competitor identifier.

kindprimary | competitor

Entity role. Items in competitors are competitor; primary describes the tracked brand.

namestring

Display name used in prompts, results, and reports.

domainstring | null

Normalized hostname without a scheme, path, query, leading www, or trailing dot.

aliasesstring[]

Additional names recognized as this entity. Maximum: 10.

statusactive | inactive

Processing status. Competitors are active exactly when tracked and inactive when suggested or dismissed.

competitor_statetracked | suggested | dismissed | null

Competitor management lifecycle state. Null for the primary brand.

created_atdatetime

Competitor creation time.

updated_atdatetime

Last competitor update time.

Matching and response statusInput such as https://www.northstar.example/pricing is stored as northstar.example. A new record returns 201 Created; reactivation by normalized domain or case-insensitive name returns 200 OK.

Request and response

Example requestcURL
curl --request POST \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors' \
  --header 'Authorization: Bearer ceyo_platform_...' \
  --header 'Content-Type: application/json' \
  --data '{"name":"Northstar","domain":"https://www.northstar.example/pricing","aliases":["Northstar AI"]}'
Example responseJSON
HTTP/1.1 201 Created

{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "competitor": {
      "id": "63ec8dad-c12f-43c8-89e4-06eb629d0977",
      "kind": "competitor",
      "name": "Northstar",
      "domain": "northstar.example",
      "aliases": ["Northstar AI"],
      "status": "active",
      "competitor_state": "tracked",
      "created_at": "2026-07-02T11:20:00Z",
      "updated_at": "2026-07-30T09:10:00Z"
    }
}
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

409domain_conflict | own_domain | invalid_state

The normalized domain belongs to another active competitor or to the primary brand.

422validation_failed | limit_exceeded

Required data is absent, aliases exceed 10, or tracked capacity would be exceeded.

429rate_limit_exceeded

Too many requests were made.

PATCH
/projects/{project_id}/competitors/{competitor_id}

Updates a competitor's name, normalized domain, aliases, or competitor_state. Omitted fields remain unchanged. Status is derived from competitor_state and cannot be submitted.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
competitor_iduuid

Competitor identifier.

Required
Request

Request body

namestring

Mutable display name. Maximum: 200 characters.

domainstring

Mutable normalized domain. Required whenever competitor_state is tracked.

aliasesstring[]

Mutable replacement list of up to 10 unique alternate names.

competitor_statetracked | suggested

Mutable lifecycle state. PATCH accepts only tracked or suggested; dismissed is set only by a dismissal or merge operation.

Response

Update competitor response envelope

project_id:uuidcompetitor:Competitor
project_iduuid

Resolved Ceyo project identifier.

competitorCompetitor

Created or updated competitor.

Object

Competitor

iduuid

Unique competitor identifier.

kindprimary | competitor

Entity role. Items in competitors are competitor; primary describes the tracked brand.

namestring

Display name used in prompts, results, and reports.

domainstring | null

Normalized hostname without a scheme, path, query, leading www, or trailing dot.

aliasesstring[]

Additional names recognized as this entity. Maximum: 10.

statusactive | inactive

Processing status. Competitors are active exactly when tracked and inactive when suggested or dismissed.

competitor_statetracked | suggested | dismissed | null

Competitor management lifecycle state. Null for the primary brand.

created_atdatetime

Competitor creation time.

updated_atdatetime

Last competitor update time.

State restrictionsPATCH accepts exactly these mutable fields: name, domain, aliases, and competitor_state. A tracked competitor requires a domain. Status is set internally to active for tracked competitors and inactive for suggested competitors. Setting the state to suggested frees a tracked slot. Dismissed cannot be supplied to PATCH.

Request and response

Example requestcURL
curl --request PATCH \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors/{competitor_id}' \
  --header 'Authorization: Bearer ceyo_platform_...' \
  --header 'Content-Type: application/json' \
  --data '{"name":"Northstar AI","aliases":["Northstar","North Star"],"competitor_state":"suggested"}'
Example responseJSON
{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "competitor": {
      "id": "63ec8dad-c12f-43c8-89e4-06eb629d0977",
      "kind": "competitor",
      "name": "Northstar AI",
      "domain": "northstar.example",
      "aliases": ["Northstar", "North Star"],
      "status": "inactive",
      "competitor_state": "suggested",
      "created_at": "2026-07-02T11:20:00Z",
      "updated_at": "2026-07-30T09:10:00Z"
    }
}
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

409domain_conflict | own_domain | invalid_state

The normalized domain belongs to another active competitor or to the primary brand.

422validation_failed | limit_exceeded

Required data is absent, aliases exceed 10, or tracked capacity would be exceeded.

429rate_limit_exceeded

Too many requests were made.

DELETE
/projects/{project_id}/competitors/{competitor_id}

Soft-dismisses a competitor while retaining its mentions, rankings, citations, and visibility results.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
competitor_iduuid

Competitor identifier.

Required
Result continuityRemoval does not delete stored results. A later create request with the same normalized domain or case-insensitive name can reactivate the dismissed record.

Request and response

Example requestcURL
curl --request DELETE \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors/{competitor_id}' \
  --header 'Authorization: Bearer ceyo_platform_...'
Example responseJSON
HTTP/1.1 204 No Content
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

409invalid_state

The competitor cannot be dismissed from its current state.

429rate_limit_exceeded

Too many requests were made.

POST
/projects/{project_id}/competitors/merge

Combines duplicate competitors into one canonical target. Select 2–5 competitors, all in the same lifecycle state.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
Request

Request body

primary_iduuid

Canonical competitor to retain.

duplicate_idsuuid[]

One to four unique duplicate IDs. Together with primary_id, the selection must contain 2–5 competitors in the same state.

Response

Merge competitors response envelope

project_id:uuidcompetitor:Competitormerged_ids:uuid[]
project_iduuid

Resolved Ceyo project identifier.

competitorCompetitor

Created or updated competitor.

merged_idsuuid[]

Records now pointing to the canonical competitor.

Object

Competitor

iduuid

Unique competitor identifier.

kindprimary | competitor

Entity role. Items in competitors are competitor; primary describes the tracked brand.

namestring

Display name used in prompts, results, and reports.

domainstring | null

Normalized hostname without a scheme, path, query, leading www, or trailing dot.

aliasesstring[]

Additional names recognized as this entity. Maximum: 10.

statusactive | inactive

Processing status. Competitors are active exactly when tracked and inactive when suggested or dismissed.

competitor_statetracked | suggested | dismissed | null

Competitor management lifecycle state. Null for the primary brand.

created_atdatetime

Competitor creation time.

updated_atdatetime

Last competitor update time.

Merge behaviorAliases and retained results are associated with the canonical target. Source records remain dismissed after their aliases are moved to the canonical competitor.

Request and response

Example requestcURL
curl --request POST \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors/merge' \
  --header 'Authorization: Bearer ceyo_platform_...' \
  --header 'Content-Type: application/json' \
  --data '{"primary_id":"63ec8dad-c12f-43c8-89e4-06eb629d0977","duplicate_ids":["d732c038-d411-449c-a6cb-351b6d8a2961"]}'
Example responseJSON
{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "competitor": {
      "id": "63ec8dad-c12f-43c8-89e4-06eb629d0977",
      "kind": "competitor",
      "name": "Northstar",
      "domain": "northstar.example",
      "aliases": ["Northstar AI"],
      "status": "active",
      "competitor_state": "tracked",
      "created_at": "2026-07-02T11:20:00Z",
      "updated_at": "2026-07-30T09:10:00Z"
    },
  "merged_ids": ["d732c038-d411-449c-a6cb-351b6d8a2961"]
}
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

409mixed_states | invalid_target

The selected competitors do not share a state or the primary competitor is invalid.

422invalid_selection

Select between 2 and 5 unique competitor IDs.

422validation_failed

The merged aliases exceed the supported limit.

429rate_limit_exceeded

Too many requests were made.

POST
/projects/{project_id}/competitors/bulk_destroy

Soft-dismisses up to 25 competitors in one request, retains their stored results, and returns the dismissed IDs with 200 OK.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
Request

Request body

idsuuid[]

One to 25 unique competitor IDs to dismiss.

Response

Bulk remove competitors response envelope

project_id:uuiddismissed_ids:uuid[]
project_iduuid

Resolved Ceyo project identifier.

dismissed_idsuuid[]

Competitor IDs dismissed by this request.

Request and response

Example requestcURL
curl --request POST \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors/bulk_destroy' \
  --header 'Authorization: Bearer ceyo_platform_...' \
  --header 'Content-Type: application/json' \
  --data '{"ids":["63ec8dad-c12f-43c8-89e4-06eb629d0977","d732c038-d411-449c-a6cb-351b6d8a2961"]}'
Example responseJSON
HTTP/1.1 200 OK

{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "dismissed_ids": ["63ec8dad-c12f-43c8-89e4-06eb629d0977", "d732c038-d411-449c-a6cb-351b6d8a2961"]
}
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

422invalid_selection

Supply between 1 and 25 unique competitor IDs.

429rate_limit_exceeded

Too many requests were made.

POST
/projects/{project_id}/competitors/{competitor_id}/claim_as_brand

Promotes a competitor identity to the primary brand. Its name and aliases are added to the brand aliases, then the competitor is soft-dismissed.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
competitor_iduuid

Competitor identifier.

Required
Brand identity updateClaiming retains stored results, updates the primary brand aliases, and dismisses the competitor so it no longer consumes a tracked slot.

Request and response

Example requestcURL
curl --request POST \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors/{competitor_id}/claim_as_brand' \
  --header 'Authorization: Bearer ceyo_platform_...'
Example responseJSON
HTTP/1.1 204 No Content
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

409invalid_state

The competitor cannot be claimed from its current state.

422alias_limit_exceeded

Claiming the competitor would exceed the maximum of 10 brand aliases.

429rate_limit_exceeded

Too many requests were made.

GET
/projects/{project_id}/competitors?state=suggested

Returns the current suggested competitor dataset for the selected project, capped at 50 items. Suggested items may include visibility-rate and average-rank metrics.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
Parameters

Query parameters

statetracked | suggested

Return competitors in one lifecycle state.

OptionalDefault: suggested
qstring

Case-insensitive search across name, domain, and aliases.

Optional
domainall | with-domain | without-domain

Return all competitors or filter by whether a domain is present.

OptionalDefault: all
sortname-asc | name-desc | newest | visibility | mentions

Sort by name, creation time, visibility rate, or mention count.

OptionalDefault: name-asc
pageinteger

The 1-based page number.

OptionalDefault: 1
per_pageinteger

Number of competitors per page. Minimum: 1. Maximum: 50; this matches the maximum suggested dataset size.

OptionalDefault: 25
Response

List response envelope

project_id:uuidprimary:Competitorcompetitors:Competitor[]pagination:Pagination
project_iduuid

Resolved Ceyo project identifier.

primaryCompetitor

Primary tracked brand for comparison.

competitorsCompetitor[]

Competitors matching the filters.

paginationPagination

Pagination metadata for competitors.

Object

Competitor

iduuid

Unique competitor identifier.

kindprimary | competitor

Entity role. Items in competitors are competitor; primary describes the tracked brand.

namestring

Display name used in prompts, results, and reports.

domainstring | null

Normalized hostname without a scheme, path, query, leading www, or trailing dot.

aliasesstring[]

Additional names recognized as this entity. Maximum: 10.

statusactive | inactive

Processing status. Competitors are active exactly when tracked and inactive when suggested or dismissed.

competitor_statetracked | suggested | dismissed | null

Competitor management lifecycle state. Null for the primary brand.

created_atdatetime

Competitor creation time.

updated_atdatetime

Last competitor update time.

metricsCompetitorMetrics (optional)

Included only on suggested-list items with qualifying responses; otherwise omitted.

Object

Pagination

pageinteger

Current 1-based page number.

per_pageinteger

Requested page size. Minimum: 1. Maximum: 50.

totalinteger

Total competitors matching the applied filters.

total_pagesinteger

Total pages at the current per_page value.

Object

CompetitorMetrics

visibility_ratenumber

Percentage of eligible responses that mentioned this entity, from 0 through 100.

avg_ranknumber | null

Average 1-based rank when a ranked result included the entity.

Request and response

Example requestcURL
curl --request GET \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors?state=suggested&sort=visibility&domain=all&page=1&per_page=25' \
  --header 'Authorization: Bearer ceyo_platform_...'
Example responseJSON
{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "primary": {
    "id": "10cf756e-ad42-43d7-beda-e8e9cc96cd41",
    "kind": "primary",
    "name": "Acme",
    "domain": "acme.example",
    "aliases": ["Acme AI"],
    "status": "active",
    "competitor_state": null,
    "created_at": "2026-04-12T08:00:00Z",
    "updated_at": "2026-07-28T10:30:00Z"
  },
  "competitors": [
    {
      "id": "a8223436-70dc-4bc8-89fc-99139366711c",
      "kind": "competitor",
      "name": "Orbit Labs",
      "domain": "orbitlabs.example",
      "aliases": [],
      "status": "inactive",
      "competitor_state": "suggested",
      "created_at": "2026-07-21T07:15:00Z",
      "updated_at": "2026-07-30T09:10:00Z",
      "metrics": {
        "visibility_rate": 24.17,
        "avg_rank": 4.2
      }
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "total_pages": 1
  }
}
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

422invalid_filter | validation_failed

A state, sort, or domain filter is invalid, or a pagination value is outside the supported range.

429rate_limit_exceeded

Too many requests were made.

PATCH
/projects/{project_id}/competitors/{competitor_id}

Moves a suggested competitor into the tracked set. The suggestion must have a valid normalized domain and a tracked slot must be available.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
competitor_iduuid

Competitor identifier.

Required
Request

Request body

namestring

Mutable display name. Maximum: 200 characters.

domainstring

Mutable normalized domain. Required whenever competitor_state is tracked.

aliasesstring[]

Mutable replacement list of up to 10 unique alternate names.

competitor_statetracked | suggested

Mutable lifecycle state. PATCH accepts only tracked or suggested; dismissed is set only by a dismissal or merge operation.

Required tracking stateSet competitor_state to tracked. Status is set to active internally. Any other mutable fields may be updated in the same request.
Response

Track suggested competitor response envelope

project_id:uuidcompetitor:Competitor
project_iduuid

Resolved Ceyo project identifier.

competitorCompetitor

Created or updated competitor.

Object

Competitor

iduuid

Unique competitor identifier.

kindprimary | competitor

Entity role. Items in competitors are competitor; primary describes the tracked brand.

namestring

Display name used in prompts, results, and reports.

domainstring | null

Normalized hostname without a scheme, path, query, leading www, or trailing dot.

aliasesstring[]

Additional names recognized as this entity. Maximum: 10.

statusactive | inactive

Processing status. Competitors are active exactly when tracked and inactive when suggested or dismissed.

competitor_statetracked | suggested | dismissed | null

Competitor management lifecycle state. Null for the primary brand.

created_atdatetime

Competitor creation time.

updated_atdatetime

Last competitor update time.

Request and response

Example requestcURL
curl --request PATCH \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors/{competitor_id}' \
  --header 'Authorization: Bearer ceyo_platform_...' \
  --header 'Content-Type: application/json' \
  --data '{"competitor_state":"tracked"}'
Example responseJSON
{
  "project_id": "e6c96c98-d777-40e0-94ec-48931f57782f",
  "competitor": {
      "id": "a8223436-70dc-4bc8-89fc-99139366711c",
      "kind": "competitor",
      "name": "Orbit Labs",
      "domain": "orbitlabs.example",
      "aliases": [],
      "status": "active",
      "competitor_state": "tracked",
      "created_at": "2026-07-21T07:15:00Z",
      "updated_at": "2026-07-30T09:10:00Z"
    }
}
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

409domain_conflict | own_domain | invalid_state

The normalized domain belongs to another active competitor or to the primary brand.

422validation_failed | limit_exceeded

Required data is absent, aliases exceed 10, or tracked capacity would be exceeded.

429rate_limit_exceeded

Too many requests were made.

DELETE
/projects/{project_id}/competitors/{competitor_id}

Soft-dismisses a suggested competitor so it is excluded from the active suggestion queue while retaining its discovery evidence.

Parameters

Path parameters

project_idproject UUID | project external ID

Project identifier.

Required
competitor_iduuid

Competitor identifier.

Required

Request and response

Example requestcURL
curl --request DELETE \
  --url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/competitors/{competitor_id}' \
  --header 'Authorization: Bearer ceyo_platform_...'
Example responseJSON
HTTP/1.1 204 No Content
ErrorsResponse format and status codes
Errors

Error response envelope

errorError

Structured error payload.

Errors

Error

codestring

Stable snake_case code suitable for programmatic handling.

messagestring

Human-readable explanation of the failure.

detailsobject | array | null

Structured validation or request context when available.

request_idstring

Identifier to provide when requesting support.

Example error responseJSON
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "domain", "message": "must be a valid hostname" }],
    "request_id": "req_01K1JQY1RQQ7N3C5H1K6J0P8AT"
  }
}
Errors

Status codes

401invalid_api_key

Authorization bearer token is absent or invalid.

403forbidden

The API key lacks the required competitor capability or cannot access this scope.

404not_found

Project, location, or competitor was not found.

409invalid_state

The competitor cannot be dismissed from its current state.

429rate_limit_exceeded

Too many requests were made.