The Connect API: SEO fixes that apply themselves, on any website
AI WebMaker finds what holds a website back in Google and writes the fixes. With the Connect API, the website fetches the fixes its owner approved and applies them itself, then reports back so every change can be undone.
Get a keyHow it works
- The owner analyses their website in AI Website SEO Tools and approves fixes (new search titles and descriptions for their pages).
- Your website asks
GET /changesfor what is waiting, applies each field, and reports the result with the value it replaced. - When the owner presses Undo, the same call returns an
undowith the values to put back.
Running WordPress? You do not need any code: the AI Website SEO Tools plugin does all of this.
Authentication
Make a key for your website in Connected websites. You get a key id (awk_…) and a secret (aws_…, shown once). Sign every request:
| Header | Value |
|---|---|
X-AIWB-Key | your key id |
X-AIWB-Time | the time in unix seconds (within 5 minutes of ours) |
X-AIWB-Sign | hex HMAC-SHA256 with your secret of: time, newline, method, newline, path, newline, hex SHA-256 of the body |
<?php
function aiwb_call(string $method, string $path, ?array $data, string $keyId, string $secret) {
$body = $data === null ? '' : json_encode($data);
$ts = time();
$sign = hash_hmac('sha256', $ts . "\n" . $method . "\n" . $path . "\n" . hash('sha256', $body), $secret);
$ch = curl_init('https://aiwebmaker.co' . $path);
curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Accept: application/json',
'X-AIWB-Key: ' . $keyId, 'X-AIWB-Time: ' . $ts, 'X-AIWB-Sign: ' . $sign]]);
return json_decode(curl_exec($ch), true);
}
$work = aiwb_call('GET', '/api/connect/v1/changes', null, 'awk_…', 'aws_…');
The path is the request path only, without the domain or a query string. A write's signature works once: put a random value in the body (for example "_n") so two writes in the same second never sign alike. If your server's clock is off, a refused call answers 401 with server_time: correct your clock by the difference.
Endpoints
POST /api/connect/v1/hello
Say hello and, optionally, list your pages so changes can be matched to them and today's titles are known.
{"plugin": "my-site 1.0", "full": true,
"pages": [{"path": "/about", "ref": "42", "title": "About us", "seo_title": "About | Acme", "seo_description": "…"}]}
Send "ops" (the kinds of change your website can make) and "scopes" in the hello: only those are ever queued for you. Kinds of change: seo.title, seo.description, seo.focus_keyword, post.title, post.create (an article: data with title, html, excerpt, slug, status, tags, categories, featured_image, seo), schema.site (data.json: one JSON-LD object), media.alt, redirect.add, redirect.remove.
POST /api/connect/v1/inventory
Your pages in parts ("full": true on the first part replaces the list).
{"full": true, "pages": [{"path": "/about", "ref": "42", "title": "About us", "seo_title": "About | Acme", "seo_description": "…", "focus_keyword": "plumber nairobi", "noindex": false, "words": 640}]}
GET /api/connect/v1/changes
What is waiting. op is apply or undo (for an undo, put back the value you reported as before).
{"ok": true, "changes": [{"id": 17, "op": "apply", "summary": "Search titles",
"items": [{"id": 301, "type": "seo.title", "target": {"path": "/about", "ref": "42"}, "value": "About Acme | Plumbers in Nairobi", "data": null}]}]}
POST /api/connect/v1/changes/{id}
Report what you did, item by item. On apply, send the value you replaced as old: it is what Undo puts back.
{"op": "apply", "items": [{"id": 301, "ok": true, "status": "applied", "before": "About", "target": {"ref": "42", "url": "https://example.com/about/"}}]}
POST /api/connect/v1/visits
Optional: daily page views, so the owner sees real traffic next to the estimates. No personal data.
{"days": [{"day": "2026-10-08", "path": "/about", "views": 31, "visitors": 22}]}
GET /api/connect/v1/status
Your website's score, visits now and within reach, the next best move and the account's credits, for a dashboard.
POST /api/connect/v1/sso
{"to": "report"} (or workspace, changes, connections, credits, blog, keywords) → a one-time link (60 seconds) that opens the owner's account, signed in.
POST /api/connect/v1/bye
Close the connection (for example when your integration is removed).
Limits
120 requests a minute per address. Check for work every hour, or every few minutes while the owner is working. Changes and visits stay with the owner's account; the owner can disconnect at any time.