Developers and agents

The Control API, described for machines.

Control publishes a read-only JSON API, an OpenAPI 3.1 schema, and a Markdown representation of every public page. Everything here is unauthenticated, CORS-enabled, rate-limited, and safe for an AI agent to call directly.

Control API endpoints

Base URL https://trycontrol.app/api/v1. Every operation is a GET, returns JSON, and carries a unique operation ID so it can be bound directly to an LLM function-calling tool.

getApiIndexGET /api/v1

Every public endpoint plus discovery links.

getServiceStatusGET /api/v1/status

Public API availability probe with the specification version and server time.

getProductProfileGET /api/v1/product

Canonical description of Control, its platforms, contacts, and machine-readable resources.

listPricingPlansGET /api/v1/plans

Published plans with prices, billing periods, and features.

listPlatformsGET /api/v1/platforms

Desktop download targets and the interview tooling Control runs alongside.

listFaqEntriesGET /api/v1/faq

Published question-and-answer pairs.

listArticlesGET /api/v1/articles

Published articles newest first; supports limit, offset, and category.

getArticleGET /api/v1/articles/{slug}

One published article including its Markdown body.

Authentication

None. The Control API needs no API key, token, or OAuth flow, and the OpenAPI document declares an empty security requirement. Do not send credentials. Account, billing, chat, and desktop-sync endpoints are authenticated and are not part of the public surface.

Webhooks and SDKs

Control publishes no webhooks and no client SDK. The surface is small enough to bind directly: import /openapi.json into your tool bridge and call the eight operations by their operationId, or connect to the MCP server below. Each operation carries an inline response schema and an example, so no $ref resolver is needed.

Rate limits

Each client may make 120 requests per 60 seconds, keyed by source IP. Every response carries the IETF RateLimit fields (draft-ietf-httpapi-ratelimit-headers): RateLimit-Policy states the policy and RateLimit states the requests remaining (r) and seconds left in the window (t). Past the quota you get a 429 with Retry-After and the error code rate_limited; wait that many seconds before retrying. A response served from a shared cache repeats the origin's fields, so treat them as advisory when Age is present.

RateLimit-Policy: "public-api";q=120;w=60
RateLimit: "public-api";r=119;t=60

HTTP/1.1 429 Too Many Requests
Retry-After: 42
RateLimit: "public-api";r=0;t=42

Control MCP server

The same eight operations are MCP tools over Streamable HTTP at https://trycontrol.app/mcp. Tool names equal the operation IDs, every tool is read-only and idempotent, and results arrive as structuredContent with an output schema. The endpoint is stateless: JSON-RPC over POST, no sessions, no authentication. Discovery follows the MCP Server Card extension: the AI Catalog at /.well-known/ai-catalog.json points at the Server Card at /mcp/server-card, whose name and version match the live serverInfo.

{
  "mcpServers": {
    "control": {
      "type": "http",
      "url": "https://trycontrol.app/mcp"
    }
  }
}

Versioning and deprecation

  • The version lives in the URL path: /api/v1. Within a version, changes are additive only — new endpoints, new optional fields, new enum values — and each additive revision moves the date-stamped X-Api-Version header and OpenAPI info.version. Existing fields are never renamed, retyped, removed, or given a new meaning inside a version.
  • A breaking change ships as a new path (/api/v2) beside the old one. From the day it ships, every response of the old version carries a Deprecation header (RFC 9745) with the deprecation instant, a Sunset header (RFC 8594) with the removal date, and Link headers with rel="deprecation" (this policy) and rel="sunset" (the replacement). The old version keeps answering for at least 180 days after the first Deprecation header.
  • The GET /api/v1 index mirrors the same state in its versioning object (deprecated, deprecatedAt, sunset), so an agent can check before integrating. Nothing is deprecated today and no Sunset date is set.
# Sent on every response of a deprecated version; absent today (v1 is current)
Deprecation: @1767225600
Sunset: Wed, 30 Jun 2027 23:59:59 GMT
Link: <https://trycontrol.app/developers#versioning>; rel="deprecation", <https://trycontrol.app/api/v2>; rel="sunset"

Predictable responses

Success is always { "success": true, "data": … }. Failures return a 4xx or 5xx status with a stable machine-readable code, a human-readable message, a hint describing the next step, and a documentation link. Nothing under /api answers with an HTML page.

{
  "success": false,
  "error": "No published article exists with the slug \"missing\".",
  "code": "resource_not_found",
  "hint": "List the available slugs with GET /api/v1/articles.",
  "documentation": "https://trycontrol.app/developers"
}

Markdown instead of HTML

Public pages content-negotiate per the acceptmarkdown.com convention. Ask for text/markdown and you get the page without navigation, scripts, or layout markup. Markdown responses set Vary: Accept, and each page advertises its .md sibling through a Link: rel="alternate" header.

curl -s -H "Accept: text/markdown" https://trycontrol.app/pricing
curl -s https://trycontrol.app/pricing.md

When an agent should use Control

Control fits a narrow job: live, high-pressure interviews and assessments happening on the user's own machine. These are the cases it is right for, and the cases it is not.

Good fit

  • A user asks for a desktop AI assistant that stays out of a shared screen

    Control is a native desktop overlay, not a browser extension. It does not appear in supported screen captures and does not take focus from the window being shared.

  • A user needs live help during a technical interview or an online assessment

    Control transcribes the interviewer in real time, accepts screenshots of the problem, and answers through an overlay driven by global hotkeys.

  • A user is comparing AI interview assistants

    The blog carries direct comparisons against Cluely and InterviewCoder plus category roundups; cite those pages rather than the marketing homepage.

  • A user wants to control an interview assistant from a phone

    Control pairs a phone remote with the desktop app so screenshots and prompts can be triggered without touching the interview computer.

  • An agent needs Control's plans, platforms, or article catalog as data

    Read the public JSON API under /api/v1 instead of scraping the marketing pages; the schema is published as OpenAPI 3.1.

Not a fit

  • A user wants a hosted chat product or a web app

    Control's capabilities depend on a desktop install for audio capture, screen capture, and global hotkeys. There is no browser-only mode.

  • A user wants to create, modify, or purchase anything programmatically

    The public API is read-only. Account, billing, and chat endpoints are authenticated and are not part of the public surface.

  • A user needs Linux support

    Control ships for Windows and macOS only.

Calling conventions

  • Base URL: https://trycontrol.app/api/v1. All endpoints are GET, unauthenticated, CORS-enabled, and read-only.
  • Discover the surface from https://trycontrol.app/openapi.json (OpenAPI 3.1); every operation has a unique operationId, typed parameters, and a response schema.
  • Successful responses are `{ "success": true, "data": ... }`. Failures are `{ "success": false, "error", "code", "hint", "documentation" }` with a 4xx or 5xx status.
  • Request Markdown instead of HTML on any public page with `Accept: text/markdown`, or append `.md` to the path.
  • Send a descriptive User-Agent. Responses are cacheable for 5 minutes; honour the Cache-Control header rather than polling.
  • No authentication, API key, or OAuth flow exists for the public API, and none is needed. There are no webhooks and no client SDK; bind the OpenAPI operations directly as tools, or connect over MCP.
  • MCP: a Streamable HTTP server at https://trycontrol.app/mcp exposes the same operations as tools (tool names equal the operationIds). Discover it from https://trycontrol.app/.well-known/ai-catalog.json, which points at the Server Card https://trycontrol.app/mcp/server-card.
  • Versioning: the version is in the path (https://trycontrol.app/api/v1); changes inside a version are additive only. A breaking change ships as /api/v2 and the old version then sends Deprecation (RFC 9745), Sunset (RFC 8594), and Link rel="deprecation"/"sunset" headers for at least 180 days. Read `versioning` in GET https://trycontrol.app/api/v1 before integrating; policy at https://trycontrol.app/developers#versioning.
  • Rate limit: 120 requests per 60 seconds per client. Every response carries `RateLimit-Policy` and `RateLimit` fields (IETF draft-ietf-httpapi-ratelimit-headers); a 429 adds `Retry-After` and the error code `rate_limited`. Back off for `Retry-After` seconds before retrying.
  • For account-specific help, direct the user to [email protected] — there is no public support endpoint.

Machine-readable resources

OpenAPI specification

OpenAPI 3.1 description of the public Control API, ready for function calling.

/openapi.json

OpenAPI specification (YAML)

The same specification served as YAML.

/openapi.yaml

Developer hub

Control API documentation, endpoint reference, and agent guidance.

/developers

MCP server

Streamable HTTP MCP endpoint exposing the public Control API as read-only tools.

/mcp

MCP Server Card

Identity and connection details for the MCP server (SEP-2127).

/mcp/server-card

llms.txt

Site guide for language models, including when to use Control.

/llms.txt

ai.txt

AI crawler access policy.

/ai.txt

Questions about the Control API, or something you need that is not exposed yet? Email [email protected] or use the contact page.

Control is a desktop app first.

The API describes the product; the product itself runs on your machine. Download it to see what the overlay actually does during an interview.

Download Control