# LLM use cases

This page is for someone connecting an AI client to Tinylytics and wondering what that is actually good for. Tinylytics will not run your model, write to your CMS, or publish on your behalf. The client reads our data; you decide what happens next.

Three doors cover almost everything. [MCP](/docs/mcp) is the one to use when you are in a chat and want to ask a question or poke a site. The [HTTP API](/docs/api) is the one to use when you are writing a program that needs to ignore an issue or recheck a URL. [Webhooks](/docs/developer/webhooks) are the one to use when something happens and you want that program to wake up instead of polling. Webhooks need a paid plan. Writes need a full-access key (`tly-fa-…`).

## Fix broken links with a human in the loop

[Content monitoring](/docs/monitoring/content) already crawls your site and lists broken links and mixed content. The useful agent loop is not “the model patches production.” It is: we tell you something broke, the model drafts a change, you approve it, your publishing tool applies it, then Tinylytics is told the row is handled.

Subscribe a webhook to `content_issue` from Account Settings, or have the client call `create_webhook` / `POST /webhooks` with that event type. Store `signing_secret` from the create response; it is not shown again. The payload’s `check.url` is the dead link or mixed resource. `check.found_on_url` is the list of pages on your site where it was found — that is the post or template to edit. `status_code` and `error_message` tell the model whether it is a 404, an `http://` asset on an `https://` page, or something else.

Give that object to the model and ask for a concrete edit: retarget the link, remove it, or swap the asset. Keep a human in the middle. Ghost, WordPress, Micro.blog, and git-backed sites all have their own APIs for the publish step; Tinylytics does not speak any of them.

When the change is live, `PATCH /sites/:id/content/:content_check_id/ignore` takes the row out of the open queue, or `POST /sites/:id/content/:content_check_id/recheck` asks Tinylytics to look again. Both need a full-access key and an active subscription. Recheck returns `202` immediately; poll `GET /sites/:id/content` for the result.

Webhooks fire when an issue is new or its type changes, not on every daily crawl of the same 404. For a backlog, poll `GET /sites/:id/content` and walk `issues.broken_links` and `issues.mixed_content` the same way. MCP `get_content` can read that queue; ignore and recheck are HTTP-only for now.

If the queue is mostly other people’s sites, turn on **Only check this site** in Content Settings before you automate anything. The same GET returns that flag.

## Ask what the dashboard is slow to answer

MCP is built for questions like “what moved this week” or “which referrer showed up on `/notes`.” `list_hits` with a path or a grouped referrer, together with `list_insights`, covers those without assembling a report by hand.

[Insights](/docs/analytics/insights) already writes a daily paragraph from the same data. Use the client for the follow-up — why that path jumped, who sent the extra traffic — not for a second copy of the email. A spike on one path is the same idea with a narrower filter: grouped hits for that path, then referrers and countries. The model should cite the numbers it was given. If it cannot, it is guessing.

## Tell Tinylytics what you shipped

Insights is good at spotting the Wednesday spike and has no idea you sent a newsletter on Tuesday. `POST /sites/:id/signals` is how you close that gap: an `occurred_at`, a short `title`, and optionally a `description` and a `category` of `newsletter`, `social`, `launch`, `maintenance`, `content`, `podcast`, or `other`. The next report reads those alongside the traffic and attributes the jump instead of admiring it.

If the agent is already the thing that publishes the post or sends the campaign, have it write the signal in the same step. Set `external_id` and re-sending the same signal updates that row rather than adding a second one. This needs a full-access key, an active subscription, and insights enabled on the site. It is HTTP-only: MCP reads insights, it does not write signals.

## See which assistants are reading you

Agent visits are counted separately from human hits, so questions about them are their own thing: which pages ChatGPT fetched to answer somebody, whether a training crawler is working through your archive, which assistant turned up first. `list_agent_visits` filters by `category` — `answer_fetch`, `search_index`, `training`, or `ai_crawler` — and by `path`, `agent_name`, or `provider`.

Give the model one caveat along with the data. Most crawlers never run JavaScript, so these rows only exist where your backend reported the request; [AI agent traffic](/docs/analytics/ai-agent-traffic) has the middleware for that. An empty queue can mean nobody came, or it can mean nobody told us.

## Ask about every site in one question

With one site you can simply look at it. A portfolio is where a client earns its keep. `list_sites` with `start_date` and `end_date` returns `period_hits` and `period_unique_hits` for every site in a single call, so “which of my sites moved last month” does not turn into eleven separate lookups. Ultra accounts that have bundled sites can read those bundles with `list_groups` and `get_group`.

Keys stay personal. Call `list_accounts` first, then pass a team `id` as `account_id` on everything that follows, or omit it to stay on your own account.

## Clear a spam queue from chat

[Spam Analysis](/docs/analytics/spam) is a fourteen-day look at obviously non-human traffic. From an agent, `list_spam_hits` shows the same queue as the dashboard, and `delete_spam_hits` removes rows you have actually looked at. That needs a full-access key. Prefer an ignore rule when the same junk will keep arriving; deletion is permanent.

## Watch the things that expire

`get_uptime` returns more than up or down. It carries the SSL expiry date and the days left on it, the domain expiry and its remaining days, the current status, and recent downtime. That makes a standing question — anything expiring in the next thirty days? — a `list_sites` call followed by one `get_uptime` per site. It catches the certificate nobody renewed and the domain that quietly lapses in March.

It needs an active subscription, and it fails on a site where uptime monitoring was never switched on. `update_site_features` with `uptime: true` is the fix.

## Draft something you still post yourself

A `monitor_down` webhook is enough context for a short status note: which site, when it started, what error Tinylytics recorded. A `new_insight` payload is enough context for a writing plan: which pages moved, which referrers appeared, what Tinylytics already recommended. In both cases the model drafts and you publish.

## Start a trial for a person, then hand the keys back

If you are an agent setting Tinylytics up for someone else, [instructions for agents](/docs/agent_signup) is the whole protocol: you start the signup, they choose a password in their browser, and only then do you connect MCP. After that, `create_site` and the embed snippet in [Getting started](/docs/getting-started/embed) are enough to get the first hit. `update_site_features` then turns on uptime and content monitoring, which is what most of the loops above assume is already running.