Calling tools
The request, the response, discovery and the OpenAPI document.
Every tool is one endpoint:
POST https://seolyticize.com/api/v1/tools/{name}with your key as a bearer token and the tool's input as the JSON body. There are no other verbs and no path parameters: a client id, a domain or a date range is a field in the body.
- cURL
- TypeScript
- CLI
curl -X POST https://seolyticize.com/api/v1/tools/get_rank_summary \
-H "Authorization: Bearer $SEOLYTICIZE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"clientId":"<clientId>","trackerId":"<trackerId>"}'import { createClient } from "@seolyticize/sdk";
const seo = createClient({ apiKey: process.env.SEOLYTICIZE_API_KEY! });
const summary = await seo.tools.get_rank_summary({
clientId: "<clientId>",
trackerId: "<trackerId>",
});seolyticize call get_rank_summary --client-id=<clientId> --trackerId=<trackerId>The response
A result comes back with status 200 under data:
{ "data": { "…": "the tool's result" } }A failure comes back under error, as one sentence written for the caller:
{ "error": "That API key is not valid." }Nothing internal is ever included: a request that could not be completed says only that, and the real reason stays in Seolyticize's own logs. Errors and limits lists every status code.
Input
The body is the tool's input exactly as its JSON Schema describes it. Send {} for a tool that takes nothing. Fields you leave out take their defaults. A missing required field, or a value of the wrong type or outside its bounds, is a 400 whose message names the field. Fields the schema does not declare are ignored.
Dates are strings in the format each schema states (2026-01-01 or 20260101 — check the tool's schema). Ids such as clientId and trackerId come from other tools: list_clients for clients, list_rank_trackers for trackers.
Discovery
curl https://seolyticize.com/api/v1/tools \
-H "Authorization: Bearer $SEOLYTICIZE_API_KEY"GET /api/v1/tools lists the tools your key may call — each with its name, title, description, permission, whether it addresses one client (clientScoped), whether it only reads (readOnly), whether it can cost money (spends), and its input as JSON Schema — plus your key's role and reach. It is generated from the same registry that runs the calls, so build against it rather than against a copy of these pages: a tool added to the platform appears here the day it ships.
OpenAPI
GET https://seolyticize.com/api/v1/openapi.jsonThe whole surface as OpenAPI 3.1, public and unauthenticated, for client generators, Postman and API gateways. It describes what exists, not what any one key may do. The API reference in the sidebar is generated from it.
Same rules on every surface
REST, MCP, the SDK and the command line all go through one registry. The tenancy check, the role check, input validation and error wording are the same whichever way a call arrives, so a call refused over REST is refused over MCP for the same reason. Every call is also recorded in the agency's activity trail with the surface it came from (list_api_activity reads it).