create_editorial_velocity
create_editorial_velocityMeasure how many articles a website publishes per month and per week (free tool)
Reads the sitemap of one website and the date shown on each of its pages, then counts the articles published over the last 12 full months (UTC), per month, per section, per language, and how many articles were updated. Works with any CMS.
What is counted. Only articles, dated by the publication date the site itself shows, read in this
order: structured data (JSON-LD datePublished), meta tags, an itemprop attribute, a labelled date in the
visible text such as "Published on" or "Publié le", the first line of a press release ("City, March 12,
2026"), then the first <time> element ("Updated on" is never a publication date). A page is an
article when it is typed as one (JSON-LD Article, BlogPosting, NewsArticle and similar types, or an
article:published_time meta tag), when its date comes from such a visible label or from the first line of
a press release (no inference needed), or when it belongs to a section without article markup whose pages
read are mostly dated by an itemprop attribute or a <time> element: that section is listed in
method.inferredSections (the exact rule is described there) and its dated pages are counted (never its
future dates, never an agenda or event section). Other dated pages are not counted, their number is
returned as publications.otherDatedPages.
Articles that share the same day are counted like any other: a section where at least 80% of the pages
counted share one day is only reported in method.sameDaySections (grouped publication, or dates changed
in bulk), never excluded.
Pages read without any date are never counted, their number is returned as method.undatedPages; a page
served but not HTML (a PDF) is one of them, not a failure in method.pagesFailed. An article republished
with a new date counts as a publication.
Asynchronous, poll the result. This call only starts the analysis and answers HTTP 202 with an
analysisId and a pollUrl. Call GET /api/v1/tools/editorial-velocity?analysisId=... every 5 seconds
until status is done or failed; an analysis takes from 1 to 45 minutes depending on the size of the
site. MCP clients must call the get_editorial_velocity tool again until the status is terminal.
Up to 1500 pages read. Below that, every page of the sitemap modified in the window is read. Above it,
pages are sampled section by section (method.strata sections, a section being the first path segment):
a few pages of each section are read first, a section whose pages show no publication date is left out
and listed in method.undatedSections, and the rest of the 1500 pages is shared among the dated sections.
Counts are then extrapolated, method.sampled is true and publications.ci95 gives the 95 % confidence
interval of the yearly total. A section whose reading was stopped by the time or page budget, or by too
many failed pages, before any dated page was read is listed in method.undecidedSections: it is counted nowhere, neither in the total
nor in ci95, and the result is then a sample. A total of 0 with ci95 present, or with
method.undecidedSections not empty, comes from a sample: it does not prove that the website published
nothing.
Same domain, reused for 7 days. An analysis of the same domain finished less than 7 days ago is
returned as is, and an analysis of the same domain still running is shared rather than started twice.
HTTP 200 with reused true when it is already done; nothing is read again, and your daily quota is given
back in both cases (quotaReleased true; false in the rare case where giving it back failed).
Domain. Send a host name or any URL of the site, it is reduced to its host (https://www.example.com/blog/
becomes example.com). Subdomains are kept, blog.example.com is not example.com. IP addresses, local
names and unknown suffixes return 400 INVALID_DOMAIN.
Tiers, per UTC day.
Without an API key, free anonymous tier: 1 analysis per day per IP address.
Signed-in account, or API key of an account whose plan includes API access: 3 analyses per day.
Anti-loop ceiling, every tier: 50 analysis requests per day per account, or per IP address without one, reused answers included, never given back except after SERVICE_BUSY. Beyond it, 429 RATE_LIMITED with details.reason CREATE_ATTEMPTS_CEILING.
The API key of an account whose plan does NOT include API access does not authenticate, and the
call returns 401. Remove the Authorization header to use the free anonymous tier instead.
Paid analysis beyond the free ones, 20 tokens, ONLY WITH THE USER'S EXPLICIT AGREEMENT. When an
account has used its free analyses of the day, the call returns 429 RATE_LIMITED with
details.paidOption (tokens, the price, and balance, the token balance of the account, null when
unknown). So does the 429 FREE_CAPACITY_REACHED of an account: paid analyses do not count towards the
daily capacity shared by all accounts, and paid true on that refusal pays for the analysis instead. Never retry with paid true on your own: tell the user the price and their balance, and send
the same request again with "paid": true only after they agree. It then charges 20 tokens and starts
the analysis (tokensCharged in the answer). The tokens are given back when the analysis service
refuses the request, when the answer is reused (an analysis of the same domain less than 7 days old,
or already running: tokensRefunded true), and when the analysis fails (at the first read that sees
failed, or within the next hours if nobody reads it). With free analyses left, paid true uses a free
one and charges nothing. Without an account, paid true returns 401. A balance below the price returns
402 INSUFFICIENT_TOKENS and nothing is charged or started. A 500 TOKENS_NOT_CONSUMED means the outcome of
the debit could not be confirmed and nothing was started; if tokens were taken, they are given back
automatically within the next hours. Do not retry with paid true before telling the user.
Quota headers: X-RateLimit-Limit, X-RateLimit-Used, X-RateLimit-Remaining,
X-RateLimit-Reset (Unix time of the next UTC midnight). Retry-After is set on 429 and 503.
A 502 or 503 answer gives the consumed quota back, and so does a 429 FREE_CAPACITY_REACHED
and a reused answer; SERVICE_UNAVAILABLE consumes none.
Request format. Send the body as JSON with Content-Type: application/json: any other
content type returns 415. Without an Authorization header, a request sent by a web page of
another site (an Origin other than the SERPmantics app, or Sec-Fetch-Site: cross-site)
returns 403. Server-to-server calls send no Origin header and are not affected.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| paid | No | Accounts only. True to pay 20 tokens for this analysis when the free analyses of the day are used up. Send it only after the user agreed to the price (see details.paidOption of the 429). Ignored while free analyses are left: a free one is used and nothing is charged. | |
| domain | Yes | Host name of the website, or any URL of it. Reduced to its host, subdomain kept, www removed. |