Skip to content
01Developers

Blck Alpaca API & Developer Resources

Everything this site offers in machine-readable form: OpenAPI specification, Markdown variants of the content, llms.txt. No sign-up, no keys.

What this is and what it is not

These endpoints serve the forms and the search of this website. They are not a product API. There is nothing to integrate with, no account, no availability guarantee.

They are documented anyway, for one reason: anyone reading the site programmatically should not have to reconstruct the endpoints from frontend code. And anyone running into a rate limit should know where it sits beforehand.

Internal endpoints are deliberately absent from the specification: cache invalidation, the redirect map, the spam filter fields.

Resources

Fixed URLs. They do not change.

URLPurpose
/mcpMCP server for the knowledge base. Streamable HTTP, revision 2026-07-28, POST only.
/openapi.jsonOpenAPI 3.1, JSON. Every public endpoint with schemas, operationId and error codes.
/api/openapi.yamlThe same specification as YAML.
/llms.txtStructure of the site in prose: services, knowledge base, studies, per language.
/llms-full.txtLong form with substance rather than a bare link list.
/sitemap-index.xmlComplete URL list, chunked.
/feed.xmlRSS of the blog posts.
/robots.txtCrawler rules including the content signal (ai-train=no).

Authentication

None. The public endpoints have no keys, no tokens, no accounts.

Two of them still cannot be scripted sensibly: the contact form and the SEO audit require a token that only the page generates in the browser. The specification marks them browser-only. A 200 there also does not mean the request was processed. Requests detected as automated receive the same response as real ones.

Quotas

Rate-limited endpoints expose their state on every response, not just on the 429. Read the headers and you never have to hit the wall to learn the limit.

Two formats ship side by side: RateLimit and RateLimit-Policy per IETF draft-ietf-httpapi-ratelimit-headers-11, plus the legacy RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers most client libraries read. As of August 2026 the draft is not an RFC.

Where more than one quota applies, as with the chat counting per IP and per session, the first two headers name all of them. The legacy headers name only the tightest.

Response headers of a chat call

RateLimit-Policy: "chat-ip";q=50;w=86400, "chat-session";q=20;w=86400
RateLimit: "chat-ip";r=49;t=86399, "chat-session";r=19;t=86399
RateLimit-Limit: 20
RateLimit-Remaining: 19
RateLimit-Reset: 86399
q
Requests allowed within the window.
w
Window length in seconds.
r
Requests still available.
t
Seconds until reset. A delta, not a timestamp.

MCP server

The knowledge base is also reachable as an MCP server at POST /mcp. An assistant that connects it searches the articles and pulls full texts without parsing HTML.

Transport is Streamable HTTP per revision 2026-07-28. That revision made the core stateless: no initialize handshake, no session id, no GET endpoint. Every request is a POST of its own and carries its protocol version in the MCP-Protocol-Version header. Mcp-Method is required, as is Mcp-Name on tools/call; requests whose headers disagree with the body are rejected.

No sign-up. The same quota applies as to the other endpoints, and the content may be used with attribution.

ToolDescription
search_knowledge_baseFull-text search across title, short definition and primary keyword of the Blck Alpaca knowledge base articles (SEO, GEO, AI agents, marketing automation). Returns matches with URL and path triple; get_knowledge_article fetches the full text.
list_knowledge_categoriesReturns the structure of the knowledge base: every category with its topics, each with slug and URL. The entry point when no search term is known.
list_knowledge_topic_articlesAll published articles of one topic. Category and topic slug must match and come from the same language; if they do not, the response says why.
get_knowledge_articleFull text of a knowledge base article as Markdown, plus short definition, key takeaways, sourced statistics and FAQ. The path triple comes from search_knowledge_base or list_knowledge_topic_articles.

List the tools

curl -X POST "https://blckalpaca.at/mcp" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/list" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Endpoints

Generated from the same specification served at /openapi.json. This table cannot go stale.

EndpointoperationIdDescription
GET /api/knowledge-searchsearchKnowledgeBaseSearch the knowledge baseFull-text search across title, definition and primary keyword of the knowledge base articles.
GET /api/healthgetHealthApplication statusFor monitoring.
POST /api/contactsubmitContactFormSend a contact requestTriggers a double opt-in confirmation email.
POST /api/newsletter/subscribesubscribeNewsletterSubscribe to the newsletterDouble opt-in.
POST /api/newsletter/unsubscribeunsubscribeNewsletterUnsubscribe from the newsletterExpects the token from the unsubscribe link in the email.
GET /api/newsletter/unsubscribe/validatevalidateUnsubscribeTokenCheck an unsubscribe tokenChecks whether an unsubscribe token is valid without performing the unsubscribe.
GET /api/newsletter/verifyverifyNewsletterSubscriptionConfirm a newsletter subscriptionTarget of the link in the confirmation email.
GET /api/contact/verifyverifyContactRequestConfirm a contact requestTarget of the link in the confirmation email.
GET /api/chatgetChatSessionRetrieve the history of a chat session
POST /api/chatsendChatMessageMessage to the website assistantRate limited per IP and additionally per session.
POST /api/seo-auditrequestSeoAuditRequest a free SEO audit (browser only)Requires a challenge token generated in the browser when the form loads.

Error responses

Every error has the same shape: error carries a stable code, message the human-readable text, hint says what to do about it. Codes are never renamed and never reused for something else. You can branch on them.

CodeStatusHint
VALIDATION_ERROR400Check `fields` in this response — it names the concrete error per field.
INVALID_REQUEST400Usually a missing or expired challenge token. Reload the page and submit again.
MISSING_FIELDS400Add the fields listed in `fields` and send the request again.
MISSING_EMAIL400Include `email` in the JSON body.
FIELD_TOO_LONG400Shorten the field named in `fields`.
MALFORMED_BODY400Send valid JSON and set `Content-Type: application/json`.
INVALID_EMAIL400Expected an address of the form [email protected].
INVALID_EMAIL_DOMAIN400The domain has no MX records. Use a different address.
DISPOSABLE_EMAIL400Use a permanent address. Do not retry with the same one.
ALREADY_SUBSCRIBED400No retry needed — the state is already the one you wanted.
INVALID_URL400Expected an absolute URL with http:// or https://.
INVALID_WEBSITE400Expected a reachable domain.
GDPR_REQUIRED400Set `gdprConsent` to true. Without consent nothing may be stored.
INVALID_TOKEN400Tokens are single-use. Request a new one.
TOKEN_EXPIRED410Request a new token through the original endpoint.
METHOD_NOT_ALLOWED405The permitted methods are in the `Allow` header of this response.
NOT_FOUND404Check the path. An overview of the site is at /llms.txt.
UNAUTHORIZED401This endpoint is internal and expects a valid secret.
RATE_LIMIT429Wait the number of seconds given in the `Retry-After` header. `RateLimit` states the remaining quota — that header is present on successful responses too.
EMAIL_LIMIT429The limit applies per address, not per IP. Changing IP does not help. This limit is deliberately absent from the `RateLimit` header.
SPAM_REJECTED400Do not retry. If misjudged, report it by email to [email protected].
UPSTREAM_UNAVAILABLE503Temporary. Retrying with exponential backoff makes sense.
INTERNAL_ERROR500Not caused by your request. Try again later.

Examples

Two calls that work without a browser.

Search the knowledge base

curl "https://blckalpaca.at/api/knowledge-search?q=schema&locale=en"

Query the status

curl -i "https://blckalpaca.at/api/health"

Something missing or wrong

If an endpoint behaves differently from what is described here, the description is the bug. A short message is enough.

Contact