
Each local area page used to take us half a day to create and optimize.
With SEOmatic, we can create hundreds of pages in the same time, which helps our clients make the best use of their budget.
It's transformed how we deliver scalable SEO solutions.
Will Hawkins
Marketing Director, Digi-Business UK
Agents read your Search Console data, do the work, and prove what actually moved. You decide what ships.
14-Day Free Trial. $1 card check, refunded. Cancel Anytime.
The seomatic CLI runs with no install via npx. Two commands need no account; the rest use your API key. And with `tools call` it can invoke the full tool surface, the same as REST and MCP. Node 18+, zero dependencies.
Two commands need no account and no key. Copy any line and run it.
# 1. Audit any URL. No account. npx seomatic audit https://example.com # 2. Find crawl-budget waste in a server log. No account. npx seomatic logs /var/log/nginx/access.log # 3. Read your own Search Console data. export SEOMATIC_API_KEY=smk_live_... npx seomatic gsc top-queries --days 28
| Command | Auth | Description |
|---|---|---|
npx seomatic audit <url> | no account | Agent-readiness + SEO surface check for any URL. |
npx seomatic logs <access.log> | no account | Crawl-budget analysis from a server access log (or - for stdin). |
npx seomatic me | API key | Introspect the key: workspace, scopes, GSC connection. |
npx seomatic gsc top-queries | API key | Top Search Console queries. Flags: --days N, --limit N. |
npx seomatic gsc top-pages | API key | Top Search Console pages. Flags: --days N, --limit N. |
npx seomatic tools | API key | List every tool this key can call (the full surface). --group read|acts to filter. |
npx seomatic tools call <name> | API key | Invoke any tool with --data '{...}'. Proxies POST /v1/tools/{name}, the same surface as REST and MCP. |
| Flag | Meaning |
|---|---|
--json | JSON to stdout. Works on every command. |
--key <key> | API key. Overrides SEOMATIC_API_KEY. |
--api <base> | API base URL. Default https://app.seomatic.ai/api/v1. |
--days <n> | Lookback window for gsc commands (default 28). |
--limit <n> | Max rows for gsc commands (default 25). |
--data <json> | JSON argument body for `tools call`. |
--group read|acts | Filter `tools` by read-only vs acting. |
--version, -v | Print the version and exit 0. |
--help, -h | Usage and exit 0. |
seomatic audit fetches one URL and runs 10 checks, covering classic SEO and whether an AI answer engine can read the page.
reachabletitlemeta_descriptioncanonicalh1json_ldrobots_txtsitemapllms_txtsecurity_txt
npx seomatic audit https://example.com --json
{
"url": "https://example.com",
"score": 30,
"passed": 3,
"total": 10,
"checks": [{ "id": "reachable", "ok": true, "detail": "HTTP 200 in 133ms" }]
}score is passed over total as a percentage. The command exits 0 even when checks fail, because a failing check is a finding rather than a CLI error. Branch on the score, not the exit code.
The split that matters in CI: 1 means the call was wrong, 2 means we could not complete it. Retry on 2 only.
| Code | Meaning | When |
|---|---|---|
0 | Success | Command ran. Includes an audit where checks FAILED: a failing check is a finding, not a CLI error. |
1 | Usage or API error | Unknown command, missing argument, no key, 401, 403, plan gate. Also bare `seomatic` with no args. |
2 | Runtime failure | Network unreachable, DNS failure, unparseable response, HTTP 5xx. A transient outage is retried; a 401 or plan gate (exit 1) is not. |
--json writes to stdout; every error and diagnostic goes to stderr. Piping stdout is therefore safe even when a command fails.
npx seomatic audit https://example.com --json 2>/dev/null | jq .score
Errors are one stable shape, which is what a script or agent should branch on. With --json the object also goes to stdout, so a wrapper never has to read stderr.
{ "error": "Missing or invalid API key" }Each of these is a complete, runnable snippet.
# Fail a build when a page regresses
score=$(npx seomatic audit "$URL" --json | jq -r .score)
[ "$score" -ge 80 ] || { echo "SEO score $score < 80"; exit 1; }
# List every check that failed
npx seomatic audit "$URL" --json | jq -r '.checks[] | select(.ok|not) | .id'
# Find AI crawlers wasting budget on errors
npx seomatic logs access.log --json | jq -r '.bots[] | select(.isAiBot and .wastedCrawlPct > 20)
| "(.bot) (.wastedCrawlPct)% wasted"'
# Retry only on runtime failures, never on your own bad call
for i in 1 2 3; do
npx seomatic me --json && break
[ $? -eq 2 ] || break
sleep $((i * 2))
done| Symptom | Cause | Fix |
|---|---|---|
Missing or invalid API key | No key, or a typo. | export SEOMATIC_API_KEY=smk_live_..., then run seomatic me. |
A tool is missing from `tools` | Scope, plan, or a missing connection. | seomatic me shows scopes, plan and GSC state. |
gsc returns nothing | No connected property, or the 2-3 day Google lag. | Connect Search Console, or widen --days. |
Acting tool returns a plan gate | agents:act needs the Infrastructure plan. | Upgrade, or use the read-only tools. |
logs reports 0 bots | The log has no user-agent field. | Use combined format, which ends with the quoted UA. |
Exit 2 with fetch failed | Network, DNS, proxy, or a wrong --api. | Check connectivity; omit --api unless self-hosting. |
seomatic me --json is the fastest first report to include when asking for help.