For an AI agent that can change a site's code and deploy it. You connect the site completely — IndexNow, analytics, a crawl, and **Search Console with no person clicking in Google** — in four calls and one deploy.

Base URL `https://seolyticize.com`. Every tool is `POST /api/v1/tools/{name}` with a JSON body and `Authorization: Bearer <key>`, or the same tools over MCP at `https://seolyticize.com/api/mcp`.

## 1. Get a key for your site

Ask the agency owner for an **invite code** (they make one with `create_invite_code`). Trade it, with your domain, for a key that reaches your site's client and nothing else. No key is needed for this call:

```bash
curl -s -X POST https://seolyticize.com/api/v1/claim \
  -H "Content-Type: application/json" \
  -d '{"inviteCode": "inv_…", "domain": "example.com"}'
```

The answer has `apiKey` (shown once — store it as a secret), `clientId`, and the `site_admin` role: full control of that one client, none of the agency's settings, team, keys or billing.

Alternatives: the owner can mint a key with `create_api_key {name, clientId, role: "site_admin"}`, or an MCP client can sign in with `claude mcp add --transport http seolyticize https://seolyticize.com/api/mcp` and have the owner approve it for one client in the browser — no key in any config file.

## 2. Onboard

```json
onboard_site {"domain": "example.com", "framework": "nextjs"}
```

`framework` is one of `nextjs`, `astro`, `remix`, `sveltekit`, `nuxt`, `html`, `wordpress`, `other`. Calling it twice is safe: it finds the existing client instead of making another. It returns one **deploy manifest**:

- `files` — each served at exactly `path` with exactly `content` (the IndexNow key and Google's verification file);
- `head` — tags for the `<head>` (only with `verification: "meta"`);
- `analytics.install` — the analytics snippet placed for your framework, and `suggestedExclude` for signed-in areas (`data-exclude`);
- `csp` — entries to add if the site sends a Content-Security-Policy;
- `next` — what to do now.

`verification` can be `file` (default), `meta`, or `dns` (one TXT record; covers every subdomain).

## 3. Deploy

Commit and deploy the files, tags and snippet. Serve the files as-is: no redirect, no login, no HTML wrapper.

## 4. Verify

```json
verify_site {"clientId": "client_…"}
```

Checks and finishes everything: the IndexNow file; Google ownership, then adds and connects the Search Console property (history included); the first analytics event; `robots.txt` and the sitemap; and starts the first crawl. It returns a checklist. Every item that is not `done` has `detail` (what is wrong) and `next` (the exact call, or what to deploy). Fix, redeploy, call it again.

## Then: the weekly loop

```json
get_next_steps {"clientId": "client_…"}
```

The same checklist, read-only, plus `weekly`: the calls that find work ranked by payoff — `get_opportunities`, `striking_distance`, `get_low_ctr_queries`, `get_content_decay`, `get_cannibalization`, `list_crawl_issues` — each with its arguments filled in. After you publish changes, `submit_indexnow` with the changed URLs.

## Every deploy, automatically

```json
create_deploy_hook {"clientId": "client_…"}
```

Returns a secret URL (once) and how to call it from GitHub Actions, Coolify, Netlify, Vercel or Cloudflare Pages. After each deploy the pipeline calls it — `curl -fsS -X POST <url>` — and the new and changed pages in the sitemap go to IndexNow. The first call records the baseline. A pipeline that knows what changed can send `{"urls": [...]}`.

## Errors

Every failure is JSON:

```json
{ "error": "A sentence for you.", "code": "search_console_no_access", "next": "What to do.", "requestId": "req_…" }
```

Branch on `code`, never on the sentence. A key can carry a per-call spending ceiling; a call may ask for less with `maxCostMicros`, never more. Quote `requestId` when asking for help — it matches the server's log. Common codes: `invalid_input`, `unauthorized`, `forbidden`, `client_not_in_reach`, `refused`, `verification_not_found`, `search_console_no_access`, `google_not_ready` (wait a minute and retry), `rate_limited` (respect `Retry-After`), `internal_error`.

## Load only what you need

`GET /api/v1/tools?group=onboarding` (or `weekly`, `technical`, `research`, `reporting`) lists just that job's tools with their schemas. Over MCP, connect to `https://seolyticize.com/api/mcp?group=onboarding`. Every tool stays callable by name either way.

## Analytics, safely

The snippet sends no query string except `utm_*` tags, sends the referrer as an origin only, and never reports paths you exclude: `data-exclude="/app/*,/dashboard/*,/verify,/reset"` on the script tag. Or `data-include="/,/blog/*"` to report only those.

More: [calling tools](./calling-tools) · [errors and limits](./errors-and-limits) · [the weekly playbook](./run-the-work) · full text for agents: `https://seolyticize.com/llms-full.txt`
