indexnowkit 0.1.1

Build and validate IndexNow submission payloads: key rules, single-host batches, the 10000-URL limit, JSON body and the single-URL GET form.


To use this package, run the following command in your project's root directory:

Manual usage
Put the following dependency into your project's dependences section:

indexnowkit

Build and validate IndexNow submission payloads in D.

IndexNow is a small protocol: you POST a JSON body naming a host, a key and a list of changed URLs, and participating search engines pick it up. The failure mode is that a malformed batch simply does nothing — you get an HTTP response and no indication that the payload was wrong. This library refuses to emit a payload it cannot prove is well formed.

Built for the ship stage of the build described at aiwebsitepipeline.com/method.html, where a generated static site has to announce a few hundred URLs without a human checking each batch. That page is also the honest statement of what this protocol is worth: it records on every run that IndexNow does not cover Google, and calls submission a request rather than an instruction. A 200 from an IndexNow endpoint means the batch was accepted, not that anything was indexed — so treat this library as a payload builder, never as evidence of coverage.

What it enforces

Straight from the protocol documentation:

  • the key is 8–128 characters, drawn only from a-z, A-Z, 0-9 and -
  • every URL in one submission belongs to the same host
  • at most 10,000 URLs go in one POST
  • the key file, when named, lives on the same host as the URLs

Usage

import indexnowkit;

auto batches = chunkUrls(allUrls, 1_000);
foreach (batch; batches)
{
    auto sub = buildSubmission(key, batch,
        defaultKeyLocation("https", "example.com", key));
    string body_ = toJson(sub);
    // POST body_ to https://api.indexnow.org/indexnow
}

Produces exactly the document shape shown in the protocol docs:

{"host":"example.com","key":"abcdef12","urlList":["https://example.com/url1"]}

For the one-off case there is the GET form:

auto url = singleUrlEndpoint("api.indexnow.org", "https://example.com/a b", key);
// https://api.indexnow.org/indexnow?url=https%3A%2F%2Fexample.com%2Fa%20b&key=...

API

functionwhat it does
isValidKey(key)length and character-set check
hostOf(url)host of an absolute http(s) URL, lower-cased, port and userinfo stripped
buildSubmission(key, urls, keyLocation = "")validated Submission, or throws
chunkUrls(urls, batchSize)batches, never larger than the protocol limit
defaultKeyLocation(scheme, host, key)scheme://host/key.txt
toJson(submission)the POST body
singleUrlEndpoint(engineHost, url, key)the GET form, percent-encoded
jsonEscape(s) / urlEncode(s)the escaping the two forms need

Everything that can fail throws IndexNowException with a message naming the offending value — a mixed-host batch reports both hosts, for instance — rather than dropping the bad entry and sending a batch you did not intend.

Tests

dub test --compiler=ldc2

Nine unittest blocks covering key validation, URL host extraction (scheme, userinfo, port, case), mixed-host rejection, the exact JSON body, escaping of quotes/backslashes/control characters, and batch chunking that loses nothing.

License

MIT.

Authors:
  • AI Website Pipeline
Dependencies:
none
Versions:
0.1.1 2026-Aug-08
0.1.0 2026-Aug-08
~main 2026-Aug-08
Show all 3 versions
Download Stats:
  • 0 downloads today

  • 1 downloads this week

  • 1 downloads this month

  • 1 downloads total

Score:
0.0
Short URL:
indexnowkit.dub.pm