hecigo Developer Resources

Everything hecigo publishes for developers and for automated clients, in one place. This page is the index; each entry below is a stable, predictable URL you can bookmark or hard-code.

If you are an AI agent, start with hecigo.com/llms.txt, which names what this site is for and when to reach for us.

Open-source n8n nodes by hecigo

hecigo maintains two n8n community nodes on npm. Both are MIT licensed, both are used outside our own projects, and both take issues.

n8n-nodes-zalo-platform

An n8n community node for the Zalo Bot Platform: send messages, photos and stickers, and manage webhooks. Zalo is the dominant messaging platform in Vietnam, and this node is what we use to reach it from an n8n workflow.

n8n-nodes-firecrawl-v2

An n8n community node covering the Firecrawl v2 API (scrape, crawl, map, search, extract, and the batch operations) against both Firecrawl Cloud and a self-hosted instance. Ten operations, six of which return web content and are not interchangeable.

All hecigo source lives under the GitHub organisation github.com/hecigo. Issues and pull requests on either node are the fastest route to a case being covered.

Machine-readable endpoints on hecigo.com

EndpointFormatWhat it is
/llms.txtMarkdown, llmstxt.orgSite summary, when to use hecigo, and a link index
/llms-full.txtMarkdownEvery public page and post concatenated, for a single fetch
/agent-instructions.mdMarkdownHow an agent should call, cite, and hand off to hecigo
/openapi.jsonOpenAPI 3.1Every endpoint on this page, described formally
/sitemap.xmlXMLEvery indexable URL, with last-modified dates
/robots.txtTextCrawl rules; no AI crawler is blocked
/blog-index.jsonJSONBlog metadata: slug, title, description, date, tags, language

Everything above is public, unauthenticated, CORS-open, and free to fetch. There is no rate limit beyond the CDN's own abuse protection. Please send a user agent that identifies your client.

The OpenAPI document

/openapi.json describes this surface in OpenAPI 3.1: every path above, the Accept negotiation on canonical page URLs, the schema of blog-index.json, and the shape of the error bodies. It is generated from the same manifest the negotiation runs on, so a retired post cannot linger in it.

Read what it is carefully, because the word "API" invites the wrong assumption: it documents a read-only website surface, not a hosted hecigo product. Every operation is a GET. There is no API key, no OAuth flow, no write path, and no multi-tenant hecigo service behind it. hecigo builds middleware inside client infrastructure, and that middleware is the client's, not a platform we rent out.

Markdown content negotiation

Every public page on hecigo.com is available as Markdown at the same URL. Send Accept: text/markdown and you get clean prose instead of a page of layout markup, per the convention documented at acceptmarkdown.com:

curl -s -H "Accept: text/markdown" https://hecigo.com/
curl -s -H "Accept: text/markdown" https://hecigo.com/blog/n8n-zalo-bot-node-what-breaks-in-production/

Responses carry Content-Type: text/markdown; charset=utf-8 and Vary: Accept, Accept-Encoding. Q-values are honoured, so a browser's Accept: text/html,...,*/*;q=0.8 still gets HTML.

Every page also ships a .md sibling if you would rather address it directly, advertised on the HTML response as Link: </index.md>; rel="alternate"; type="text/markdown":

curl -s https://hecigo.com/index.md
curl -s https://hecigo.com/developers.md

A request for a path that does not exist returns a real HTTP 404, and a request whose Accept header we genuinely cannot satisfy returns 406 Not Acceptable rather than silently handing back the wrong format. Both answer in a format you can parse; see Errors below.

Errors

Errors on this site default to JSON, shaped per RFC 9457. You do not have to ask for it:

curl -s https://hecigo.com/no-such-page/
curl -s https://hecigo.com/blog/no-such-post.md
{
  "type": "https://hecigo.com/developers/#http-404",
  "title": "Not Found",
  "status": 404,
  "detail": "There is no page at /no-such-page/ on hecigo.com.",
  "instance": "/no-such-page/",
  "code": "not_found",
  "resolution": "Fetch https://hecigo.com/llms.txt for the link index or https://hecigo.com/sitemap.xml for every URL. ...",
  "documentation_url": "https://hecigo.com/developers/#errors",
  "links": { "agentIndex": "https://hecigo.com/llms.txt", "...": "..." }
}

Branch on code, not on the prose in title or detail. There are two values: not_found and representation_not_available.

Why JSON is the default

Because of what the wire actually tells us. A browser names text/html outright in its Accept header, so a person who mistypes a URL still gets the rendered 404 page. curl, fetch, and every HTTP client library send */* or no Accept header at all, and the catch-all wildcard is not a claim to read HTML. That is the whole distinction:

What you sendWhat a 404 gives you
Nothing, or */*JSON problem document
Accept: application/jsonJSON problem document
Accept: text/markdownThe Markdown recovery map
Accept: text/html, which is what a browser sendsThe rendered 404 page

This used to be the other way round: JSON arrived only if you named it, and everything else got prose. An agent with a default header had no way to guess which header would have worked.

The status code is chosen on evidence

HTTP 404

There is no such path. The body names the path it is answering about, so an agent fetching several dead URLs can tell the responses apart, and resolution points at /llms.txt and /sitemap.xml.

HTTP 406

The path exists, but no representation matches your Accept header. The available member names the two formats it does have. Calling this a 404 would say the page is not there; calling a genuine 404 a 406 would say a dead path is real and worth retrying in another format. The 406 body is JSON in every case, including when you asked for something we have never heard of.

Including the HTML 404 page, which is how a client that cannot parse the page still finds its way to this document:

Link: <https://hecigo.com/openapi.json>; rel="service-desc"; type="application/vnd.oai.openapi+json",
      <https://hecigo.com/llms.txt>; rel="service-doc"; type="text/plain",
      <https://hecigo.com/developers/#errors>; rel="help"; type="text/html"

Error responses carry Vary: Accept, Accept-Encoding and Cache-Control: no-store, since the format of the body is chosen from a request header.

One limit worth knowing: paths that carry a non-document extension, such as /og-image.png, are not routed through negotiation at all, so their errors are the CDN's own. The document extensions .md, .txt, .json and .xml are.

What hecigo does not publish

Stated plainly so nobody wastes an afternoon looking:

  • No hosted product API. /openapi.json describes this website's read-only surface, and nothing more. hecigo builds middleware inside client infrastructure; there is no multi-tenant hecigo service to call, no API key, and no OAuth flow.
  • No write endpoints. Every documented operation is a GET.
  • No webhooks you can subscribe to. The only webhook on this domain is the enquiry-form intake, which is ours, not yours.

The public, usable surface is the two n8n nodes and the endpoints above. When there is more, this page is where it appears.

Getting in touch about the code

  • Bugs and feature requests on the nodes: open an issue on the relevant GitHub repository, with the payload that broke it.
  • Everything else: hi@hecigo.com, or the form at hecigo.com/contact.