{
  "openapi": "3.1.0",
  "info": {
    "title": "Machine Rails API",
    "version": "1.0.0",
    "description": "Covers the emerging stack of AI agents that transact on-chain: wallet and signing infrastructure, agentic payments and trading, custody, decentralized storage and the protocols and companies supplying them. Written for developers, founders and investors tracking how autonomous software holds keys and moves money.\n\nThis is a static API: JSON files are generated at build time and served read-only. /api/articles always returns the complete article list; there is no server-side filtering. Filter on the returned `articles` array (tags, date) client-side, or use the per-tag feeds at /feed/{tag}.xml. The same payload is also available at /api/articles.json for hosts that require a file extension."
  },
  "servers": [
    {
      "url": "https://machinerails.media"
    }
  ],
  "paths": {
    "/api/articles": {
      "get": {
        "operationId": "listArticles",
        "summary": "List all articles",
        "description": "Returns an envelope { _meta, articles } where articles is the full list of article objects, newest first. No query parameters are accepted; the full list is always returned. _meta.count is the total number of articles in this build.",
        "responses": {
          "200": {
            "description": "Envelope with _meta (build metadata) and articles (full array, newest first).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleList"
                }
              }
            }
          }
        }
      }
    },
    "/a/{slug}.json": {
      "get": {
        "operationId": "getArticle",
        "summary": "Get a single article by slug",
        "description": "Returns one article object (the article's JSON alternate). Note: /api/articles/{slug} cannot exist on static hosting — a file `api/articles` and a directory `api/articles/` cannot coexist in the same build output — so the single-article JSON lives at /a/{slug}.json.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Article slug (filename without .md, e.g. 2026-08-28-example).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The article object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Article"
                }
              }
            }
          },
          "404": {
            "description": "No article with that slug. (On a static host, the URL simply does not exist.)"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ArticleList": {
        "type": "object",
        "required": [
          "_meta",
          "articles"
        ],
        "properties": {
          "_meta": {
            "type": "object",
            "required": [
              "generated",
              "count",
              "static",
              "note",
              "openapi",
              "canonical"
            ],
            "properties": {
              "generated": {
                "type": "string",
                "format": "date-time"
              },
              "count": {
                "type": "integer",
                "minimum": 0
              },
              "static": {
                "type": "boolean",
                "enum": [
                  true
                ]
              },
              "note": {
                "type": "string"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "canonical": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "articles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Article"
            }
          }
        }
      },
      "Article": {
        "type": "object",
        "required": [
          "slug",
          "title",
          "date",
          "updated",
          "tags",
          "summary",
          "body",
          "sources",
          "wordCount",
          "readingTime",
          "canonical",
          "alternates"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "description": "Filename without .md, e.g. 2026-08-28-example."
          },
          "title": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date-time",
            "description": "Publication date (ISO 8601)."
          },
          "updated": {
            "type": "string",
            "format": "date-time",
            "description": "Last modification date (ISO 8601)."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "source": {
            "type": "string",
            "format": "uri",
            "description": "Optional original source URL from frontmatter."
          },
          "summary": {
            "type": "string",
            "description": "One-line dek, ~200 chars max."
          },
          "body": {
            "type": "string",
            "description": "Raw Markdown body, frontmatter stripped."
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "description": "Unique external http(s) links in the body, in order of appearance."
          },
          "wordCount": {
            "type": "integer",
            "minimum": 0
          },
          "readingTime": {
            "type": "integer",
            "minimum": 1,
            "description": "Minutes, ceil(wordCount / 200)."
          },
          "canonical": {
            "type": "string",
            "format": "uri",
            "description": "Absolute HTML URL."
          },
          "alternates": {
            "type": "object",
            "required": [
              "md",
              "json"
            ],
            "properties": {
              "md": {
                "type": "string",
                "format": "uri",
                "description": "Absolute Markdown URL."
              },
              "json": {
                "type": "string",
                "format": "uri",
                "description": "Absolute JSON URL."
              }
            }
          }
        }
      }
    }
  }
}
