Competitor Tracker & Co. API

REST API for Competitor Tracker & Co.: competitors, detected changes, snapshots, labels, weekly brief, dispatches (email, Slack and webhook delivery), billing, API keys and organization management, documented in a 74-endpoint reference at competitortracker.io/docs/api/ with base https://api.competitortracker.io/v1 and bearer API keys. No OpenAPI document is published (spec paths on api.competitortracker.io answer 401 AccessTokenMissing); the linked contract was generated from the docs by API Evangelist (2026-11-04), is partial (11 operations) and is not the provider's own document.

GitHub OpenAPI

Operations 11

GET /v1/api-keys GET /v1/api-keys #
POST /v1/api-keys POST /v1/api-keys #
GET /v1/competitors GET /v1/competitors #
POST /v1/competitors POST /v1/competitors #
DELETE /v1/org DELETE /v1/org #
GET /v1/org GET /v1/org #
PATCH /v1/org PATCH /v1/org #
GET /v1/org/invites GET /v1/org/invites #
POST /v1/org/leave POST /v1/org/leave #
POST /v1/org/own-app-domain POST /v1/org/own-app-domain #
POST /v1/org/transfer-ownership POST /v1/org/transfer-ownership #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/competitortracker-io:competitortracker-io-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

competitortracker-io-openapi-generated.yml Raw ↑
openapi: 3.1.0
info:
  title: Competitor Tracker & Co. API
  version: '2026-11-04'
  description: 'GENERATED FROM DOCUMENTATION by API Evangelist on 2026-11-04: 23 operation(s) read from 40 public documentation
    page(s) (each operation names its page in x-source). This is not the provider''s published contract; Competitor Tracker
    & Co. has published no machine-readable contract that the pipeline could find. Engine: anthropic.'
  x-evidence-tiers:
    code-example: 23
    documentation: 0
    pages-with-code: 19
    pages-read: 40
  x-generated-from: documentation
  x-provenance: generated
  x-authored-by: API Evangelist
  x-generated: '2026-11-04'
  x-generator: generate-contract-from-docs.py
  x-engine: anthropic
  x-sources:
  - https://competitortracker.io/docs/api/org
  - https://competitortracker.io/docs/api/brief
  - https://competitortracker.io/docs/api/pages
  - https://competitortracker.io/docs/api/users
  - https://competitortracker.io/docs/api/health
  - https://competitortracker.io/docs/api/labels
  - https://competitortracker.io/docs/api/billing
  - https://competitortracker.io/docs/api/changes
  - https://competitortracker.io/docs/api/api-keys
  - https://competitortracker.io/docs/api/feedback
  - https://competitortracker.io/docs/api/snapshots
  - https://competitortracker.io/docs/api/dispatches
  - https://competitortracker.io/docs/api/onboarding
  - https://competitortracker.io/docs/api/competitors
  - https://competitortracker.io/docs/api/competitors/v1/competitors/get
  - https://competitortracker.io/docs/mcp
  - https://competitortracker.io/docs/api-keys
  - https://competitortracker.io/docs/authentication
  - https://competitortracker.io/docs/getting-started
  - https://competitortracker.io/docs/scopes-and-permissions
  - https://competitortracker.io/docs/competitors
  - https://competitortracker.io/docs/track-lists
  - https://competitortracker.io/docs/changes
  - https://competitortracker.io/docs/brief
  - https://competitortracker.io/docs/labels
  - https://competitortracker.io/docs/dispatches
  - https://competitortracker.io/docs/slack
  - https://competitortracker.io/docs/billing
  - https://competitortracker.io/docs/org
  - https://competitortracker.io/docs/onboarding
  - https://competitortracker.io/docs/feedback
  - https://competitortracker.io/docs/api/org/v1/claims/token/get
  - https://competitortracker.io/docs/api/org/v1/claims/token/accept/post
  - https://competitortracker.io/docs/api/org/v1/org/leave/post
  - https://competitortracker.io/docs/api/org/v1/org/transfer-ownership/post
  - https://competitortracker.io/docs/api/org/v1/org/get
  - https://competitortracker.io/docs/api/org/v1/org/patch
  - https://competitortracker.io/docs/api/org/v1/org/delete
  - https://competitortracker.io/docs/api/org/v1/org/own-app-domain/post
  - https://competitortracker.io/docs/api/org/v1/org/invites/get
servers:
- url: https://api.competitortracker.io
paths:
  /v1/api-keys:
    get:
      operationId: get_v1_api_keys
      tags:
      - Api Keys
      summary: GET /v1/api-keys
      x-source: https://competitortracker.io/docs/api-keys
      responses:
        '200':
          description: Success (status as documented)
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl \"https://api.competitortracker.io/v1/api-keys/ $KEY_ID /usage\"  -H \"Authorization: Bearer $CT_TOKEN\
          \ \" \n The log is your audit trail. A key making calls you don't recognize is your cue to revoke it. \n What's\
          \ next \n Using OAuth2 for the path apps that sign a person in use. \n Scopes and permissions for what a key is\
          \ allowed to do. \n Getting started for your first call end to end. \n The API refer"
    post:
      operationId: post_v1_api_keys
      tags:
      - Api Keys
      summary: POST /v1/api-keys
      x-source: https://competitortracker.io/docs/api-keys
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostV1ApiKeysRequest'
      responses:
        '201':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostV1ApiKeysResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl -X POST \"https://api.competitortracker.io/v1/api-keys\"  -H \"Authorization: Bearer $CT_TOKEN \" \
          \ -H \"Content-Type: application/json\"  -d '{ \n \"name\": \"nightly-digest\", \n \"scopes\": [\"competitors:read\"\
          , \"changes:read\"], \n \"expiresAt\": \"2026-12-31T00:00:00.000Z\" \n }' \n The response carries the new key. expiresAt\
          \ is optional — leave it off for a key that never expires. \n { \n \"id\" : \"k_2a9f...\" , \n "
  /v1/competitors:
    get:
      operationId: get_v1_competitors
      tags:
      - Competitors
      summary: GET /v1/competitors
      x-source: https://competitortracker.io/docs/api/competitors/v1/competitors/get
      responses:
        '200':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetV1CompetitorsResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl JavaScript Python Go curl -X GET \"https://api.competitortracker.io/v1/competitors\" 200 400 { \n \"\
          items\" : [ \n { \n \"id\" : \"string\" , \n \"url\" : \"string\" , \n \"normalizedUrl\" : \"string\" , \n \"name\"\
          \ : \"string\" , \n \"description\" : \"string\" , \n \"displayName\" : \"string\" , \n \"faviconUrl\" : \"string\"\
          \ , \n \"competitorKind\" : \"company\" , \n \"parentCompetitorId\" : \"string\" , \n \"trackedCategories\" : [\
          \ \n \"string"
    post:
      operationId: post_v1_competitors
      tags:
      - Competitors
      summary: POST /v1/competitors
      x-source: https://competitortracker.io/docs/track-lists
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostV1CompetitorsRequest'
      responses:
        '201':
          description: Success (status as documented)
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl -X POST \"https://api.competitortracker.io/v1/competitors\"  -H \"Authorization: Bearer $TOKEN \" \
          \ -H \"Content-Type: application/json\"  -d '{ \"competitorId\": \"019e9422-7784-7026-90cb-2f30dfe0b4f4\" }' \n\
          \ Sending the id rather than the address is the better move for anything that came off a list. We already know the\
          \ company, so there is no address to normalize, no domain to check and no redirect to "
  /v1/org:
    delete:
      operationId: delete_v1_org
      tags:
      - Org
      summary: DELETE /v1/org
      x-source: https://competitortracker.io/docs/api/org/v1/org/delete
      responses:
        '200':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeleteV1OrgResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl JavaScript Python Go curl -X DELETE \"https://api.competitortracker.io/v1/org\" 200 { \n \"ok\" : true\
          \ \n } Rename the current organization. Admin-only. The name update is reflected on the next read of the org. PATCH\
          \ Rename the current organization. Admin-only. The name update is reflected on the next read of the org — Competitor\
          \ Tracker & Co. API reference for PATCH. Claim the organization's own a"
    get:
      operationId: get_v1_org
      tags:
      - Org
      summary: GET /v1/org
      x-source: https://competitortracker.io/docs/api/org/v1/org/get
      responses:
        '200':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetV1OrgResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl JavaScript Python Go curl -X GET \"https://api.competitortracker.io/v1/org\" 200 404 { \n \"id\" :\
          \ \"string\" , \n \"name\" : \"string\" , \n \"ownAppDomain\" : \"string\" , \n \"createdAt\" : \"2019-08-24T14:15:22Z\"\
          \ , \n \"updatedAt\" : \"2019-08-24T14:15:22Z\" \n } { \n \"code\" : \"string\" , \n \"message\" : \"string\" ,\
          \ \n \"resolution\" : \"string\" \n } Transfer ownership of the current organization. Instant: the current owner "
    patch:
      operationId: patch_v1_org
      tags:
      - Org
      summary: PATCH /v1/org
      x-source: https://competitortracker.io/docs/api/org/v1/org/patch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchV1OrgRequest'
      responses:
        '200':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PatchV1OrgResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl JavaScript Python Go curl -X PATCH \"https://api.competitortracker.io/v1/org\" \\ -H \"Content-Type:\
          \ application/json\" \\ -d '{ \"name\": \"string\" }' 200 404 { \n \"id\" : \"string\" , \n \"name\" : \"string\"\
          \ , \n \"ownAppDomain\" : \"string\" , \n \"createdAt\" : \"2019-08-24T14:15:22Z\" , \n \"updatedAt\" : \"2019-08-24T14:15:22Z\"\
          \ \n } { \n \"code\" : \"string\" , \n \"message\" : \"string\" , \n \"resolution\" : \"string\" \n } Read th"
  /v1/org/invites:
    get:
      operationId: get_v1_org_invites
      tags:
      - Org
      summary: GET /v1/org/invites
      x-source: https://competitortracker.io/docs/api/org/v1/org/invites/get
      responses:
        '200':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetV1OrgInvitesResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl JavaScript Python Go curl -X GET \"https://api.competitortracker.io/v1/org/invites\" 200 { \n \"items\"\
          \ : [ \n { \n \"id\" : \"string\" , \n \"email\" : \"string\" , \n \"role\" : \"owner\" , \n \"createdAt\" : \"\
          2019-08-24T14:15:22Z\" , \n \"expiresAt\" : \"2019-08-24T14:15:22Z\" \n } \n ] \n } Claim the organization's own\
          \ application domain. The verified email-domain on your account must match the submitted domain. Existing"
  /v1/org/leave:
    post:
      operationId: post_v1_org_leave
      tags:
      - Org
      summary: POST /v1/org/leave
      x-source: https://competitortracker.io/docs/api/org/v1/org/leave/post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '201':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostV1OrgLeaveResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl JavaScript Python Go curl -X POST \"https://api.competitortracker.io/v1/org/leave\" \\ -H \"Content-Type:\
          \ application/json\" \\ -d '{}' 200 409 { \n \"ok\" : true \n } { \n \"code\" : \"string\" , \n \"message\" : \"\
          string\" , \n \"resolution\" : \"string\" \n } Take on the companies an agent picked, into the organization you\
          \ already have. POST Adds the companies to your current organization under the ordinary rules, "
  /v1/org/own-app-domain:
    post:
      operationId: post_v1_org_own_app_domain
      tags:
      - Org
      summary: POST /v1/org/own-app-domain
      x-source: https://competitortracker.io/docs/api/org/v1/org/own-app-domain/post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostV1OrgOwnAppDomainRequest'
      responses:
        '201':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostV1OrgOwnAppDomainResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl JavaScript Python Go curl -X POST \"https://api.competitortracker.io/v1/org/own-app-domain\" \\ -H\
          \ \"Content-Type: application/json\" \\ -d '{ \"domain\": \"string\" }' 200 403 409 422 { \n \"orgId\" : \"string\"\
          \ , \n \"domain\" : \"string\" , \n \"backfilledCompetitorCount\" : 0 \n } { \n \"code\" : \"string\" , \n \"message\"\
          \ : \"string\" , \n \"resolution\" : \"string\" \n } { \n \"code\" : \"string\" , \n \"message\" : \"string\" ,\
          \ \n \"re"
  /v1/org/transfer-ownership:
    post:
      operationId: post_v1_org_transfer_ownership
      tags:
      - Org
      summary: POST /v1/org/transfer-ownership
      x-source: https://competitortracker.io/docs/api/org/v1/org/transfer-ownership/post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostV1OrgTransferOwnershipRequest'
      responses:
        '201':
          description: Success (shape read from the example response on the page)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostV1OrgTransferOwnershipResponse'
      x-evidence:
        kind: code-example
        language: curl
        snippet: "curl JavaScript Python Go curl -X POST \"https://api.competitortracker.io/v1/org/transfer-ownership\" \\\
          \ -H \"Content-Type: application/json\" \\ -d '{ \"to_user_id\": \"string\" }' 200 404 { \n \"ok\" : true , \n \"\
          previous_owner_id\" : \"string\" , \n \"new_owner_id\" : \"string\" \n } { \n \"code\" : \"string\" , \n \"message\"\
          \ : \"string\" , \n \"resolution\" : \"string\" \n } Leave the current organization. Sole owners must transfe"
components:
  schemas:
    GetResponse:
      type: object
      properties:
        items:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              url:
                type: string
              normalizedUrl:
                type: string
              name:
                type: string
              description:
                type: string
              displayName:
                type: string
              faviconUrl:
                type: string
              competitorKind:
                type: string
              parentCompetitorId:
                type:
                - string
                - 'null'
              trackedCategories:
                type: array
                items:
                  type: string
              labels:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    name:
                      type: string
                    color:
                      type: string
              addedAt:
                type: string
                format: date-time
              paused:
                type: boolean
              pauseReason:
                type:
                - string
                - 'null'
              nextChargeAt:
                type: string
                format: date-time
              crawlHealth:
                type:
                - string
                - 'null'
              healthDetail:
                type:
                - string
                - 'null'
              lastCrawledAt:
                type: string
                format: date-time
              lastChangeAt:
                type: string
                format: date-time
              updatedAt:
                type: string
                format: date-time
        nextCursor:
          type:
          - string
          - 'null'
    PostRequest:
      type: object
      properties:
        url:
          type: string
        displayName:
          type: string
        trackedCategories:
          type: array
          items:
            type: string
    PostCompetitorTrackerRequest:
      type: object
      properties:
        url:
          type: string
    GetProductSchedulingResponse:
      type: object
      properties:
        items:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              competitorId:
                type: string
              crawlDate:
                type: string
                format: date
              description:
                type: string
              descriptionSource:
                type: string
              priority:
                type: string
              category:
                type: string
              firstDetectedAt:
                type: string
                format: date-time
              lastDetectedAt:
                type: string
                format: date-time
              memberCount:
                type: integer
              distinctPageCount:
                type: integer
              trackedPageTotal:
                type: integer
              pageTypeCounts:
                type: array
                items:
                  type: object
                  properties:
                    pageType:
                      type: string
                    count:
                      type: integer
              members:
                type: array
                items:
                  type: object
                  properties:
                    changeId:
                      type: string
                    snapshotId:
                      type: string
                    description:
                      type: string
                    priority:
                      type: string
                    detectedAt:
                      type: string
                      format: date-time
                    trackedPageId:
                      type: string
                    pageType:
                      type: string
                    pageUrl:
                      type: string
                    pagePath:
                      type: string
                    isRepresentative:
                      type: boolean
        nextCursor:
          type: string
    GetPublicIdeabankResponse:
      type: object
      properties:
        url:
          type: string
    PostRequestInviteRequest:
      type: object
      properties:
        email:
          type: string
        source:
          type: string
        note:
          type: string
    PostRequestInviteResponse:
      type: object
      properties:
        ok:
          type: boolean
        email:
          type: string
        alreadyRequested:
          type: boolean
    PostV1ApiKeysRequest:
      type: object
      properties:
        name:
          type: string
        scopes:
          type: array
          items:
            type: string
        expiresAt:
          type: string
          format: date-time
    PostV1ApiKeysResponse:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        key:
          type: string
        scopes:
          type: array
          items:
            type: string
        expiresAt:
          type: string
          format: date-time
    GetV1Claims6F1B2C3D4E5F60718293A4B5C6D7E8F90A1B2C3D4E5F60718:
      type: object
      properties:
        status:
          type: string
        companies:
          type: array
          items:
            type: object
            properties:
              competitorId:
                type: string
              name:
                type: string
              url:
                type: string
              affiliated:
                type: boolean
              costCoins:
                type: integer
        shortfalls:
          type: array
          items:
            type: object
            properties:
              ask:
                type: string
              reason:
                type: string
        cost:
          type: object
          properties:
            companies:
              type: integer
            coinsPerCompany:
              type: integer
            coinsPerCycle:
              type: integer
        expiresAt:
          type: string
        claimedAt:
          type: string
    PostV1Claims6F1B2C3D4E5F60718293A4B5C6D7E8F90A1B2C3D4E5F6071:
      type: object
      properties:
        status:
          type: string
        organization:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
        companies:
          type: array
          items:
            type: object
            properties:
              competitorId:
                type: string
              name:
                type: string
              url:
                type: string
              affiliated:
                type: boolean
              costCoins:
                type: integer
              outcome:
                type: string
        shortfalls:
          type: array
          items:
            type: object
            properties:
              ask:
                type: string
              reason:
                type: string
        cost:
          type: object
          properties:
            companies:
              type: integer
            coinsPerCompany:
              type: integer
            coinsPerCycle:
              type: integer
        merged:
          type: integer
        expiresAt:
          type: string
        claimedAt:
          type: string
    GetV1CompetitorsResponse:
      type: object
      properties:
        items:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              url:
                type: string
              normalizedUrl:
                type: string
              name:
                type: string
              description:
                type: string
              displayName:
                type: string
              faviconUrl:
                type: string
              competitorKind:
                type: string
              parentCompetitorId:
                type: string
              trackedCategories:
                type: array
                items:
                  type: string
              labels:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    name:
                      type: string
                    color:
                      type: string
              addedAt:
                type: string
              paused:
                type: boolean
              pauseReason:
                type: string
              nextChargeAt:
                type: string
              crawlHealth:
                type: string
              healthDetail:
                type: string
              lastCrawledAt:
                type: string
              lastChangeAt:
                type: string
              updatedAt:
                type: string
        nextCursor:
          type: string
    PostV1CompetitorsRequest:
      type: object
      properties:
        competitorId:
          type: string
    DeleteV1OrgResponse:
      type: object
      properties:
        ok:
          type: boolean
    GetV1OrgResponse:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        ownAppDomain:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    PatchV1OrgRequest:
      type: object
      properties:
        name:
          type: string
    PatchV1OrgResponse:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        ownAppDomain:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    GetV1OrgInvitesResponse:
      type: object
      properties:
        items:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              email:
                type: string
              role:
                type: string
              createdAt:
                type: string
                format: date-time
              expiresAt:
                type: string
                format: date-time
    PostV1OrgLeaveResponse:
      type: object
      properties:
        ok:
          type: boolean
    PostV1OrgOwnAppDomainRequest:
      type: object
      properties:
        domain:
          type: string
    PostV1OrgOwnAppDomainResponse:
      type: object
      properties:
        orgId:
          type: string
        domain:
          type: string
        backfilledCompetitorCount:
          type: integer
    PostV1OrgTransferOwnershipRequest:
      type: object
      properties:
        to_user_id:
          type: string
    PostV1OrgTransferOwnershipResponse:
      type: object
      properties:
        ok:
          type: boolean
        previous_owner_id:
          type: string
        new_owner_id:
          type: string
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
security:
- bearer: []
tags:
- name: Api
- name: Api Keys
- name: Claims
- name: Competitor Tracker
- name: Competitors
- name: Org
- name: Product
- name: Public
- name: Request Invite
- name: Track Companies
- name: Track Lists
x-pruned:
  date: '2026-11-04'
  note: The model step failed on most pages in this run (sandbox could not read the engine key), so operations whose path
    was a marketing-site URL, another host, or a literal example value (e.g. a hard-coded claim token) were removed. Kept
    only operations whose METHOD+path match an endpoint page in the provider reference index (competitortracker.io/docs/search-index.json
    lists 74 endpoint pages). This contract is PARTIAL.
  reference_endpoint_pages: 74