openapi: '3.1.0'
info:
  title: AI & Automation Chronicle Content API
  version: '1.0.0'
  summary: Read-only access to every Chronicle post as structured JSON.
  description: |-
    The AI & Automation Chronicle Content API exposes the publication archive as JSON so agents and
    other programs can cite posts without scraping HTML. It is read-only, requires no
    authentication, and is served from the CDN edge.

    Rate limiting is applied by the CDN rather than per key. Send a descriptive User-Agent
    and cache responses for at least one hour.

    Every post also has a markdown representation: request the HTML URL with
    `Accept: text/markdown`, or append `.md` to its path.
  contact:
    name: AI & Automation Chronicle maintainer
    email: satishkc19@gmail.com
    url: https://chronicle.kcsatish.com/contact
  license:
    name: MIT
    identifier: MIT
  termsOfService: https://chronicle.kcsatish.com/privacy
servers:
  - url: https://chronicle.kcsatish.com
    description: Production
externalDocs:
  description: Developer portal
  url: https://chronicle.kcsatish.com/developers
tags:
  - name: posts
    description: The Chronicle archive.
  - name: meta
    description: Service discovery and publication statistics.
paths:
  /api/v1/index.json:
    get:
      operationId: getServiceIndex
      tags:
        - meta
      summary: Service index
      description: Returns the API version and an absolute URL for every other endpoint. Start here when discovering the API.
      responses:
        '200':
          description: Service index.
          content:
            application/json:
              schema:
                type: object
                required:
                  - service
                  - version
                  - endpoints
                properties:
                  service:
                    type: string
                  version:
                    type: string
                  documentation:
                    type: string
                    format: uri
                  specification:
                    type: string
                    format: uri
                  endpoints:
                    type: object
                    additionalProperties:
                      type: string
                      format: uri
        '406':
          description: The Accept header excluded application/json.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/posts.json:
    get:
      operationId: listPosts
      tags:
        - posts
      summary: List every post
      description: Returns all 44 posts, newest first. The response is a single page; there is no pagination because the archive is small enough to send whole.
      parameters:
        - name: type
          in: query
          required: false
          description: Filter to one series. Applied client-side by agents; the served file always contains every post.
          schema:
            type: string
            enum:
              - research
              - practice
      responses:
        '200':
          description: The full post index.
          content:
            application/json:
              schema:
                type: object
                required:
                  - count
                  - posts
                properties:
                  count:
                    type: integer
                    description: Number of posts in the response.
                  generatedAt:
                    type: string
                    format: date-time
                  posts:
                    type: array
                    items:
                      $ref: '#/components/schemas/Post'
        '406':
          description: The Accept header excluded application/json.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/posts/{postId}.json:
    get:
      operationId: getPost
      tags:
        - posts
      summary: Get one post
      description: Returns a single post including its full body as markdown.
      parameters:
        - name: postId
          in: path
          required: true
          description: Stable post identifier, for example "week-44".
          schema:
            type: string
            pattern: ^week-\d{2}$
          examples:
            latest:
              value: week-44
      responses:
        '200':
          description: One post.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Post'
                  - type: object
                    properties:
                      bodyMarkdown:
                        type: string
                        description: The full post body converted to markdown.
        '404':
          description: No post exists with that identifier.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '406':
          description: The Accept header excluded application/json.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/stats.json:
    get:
      operationId: getStats
      tags:
        - meta
      summary: Publication statistics
      description: Post counts per series, the newest post in each series, and every topic tag in use.
      responses:
        '200':
          description: Publication statistics.
          content:
            application/json:
              schema:
                type: object
                required:
                  - totalPosts
                  - bySeries
                properties:
                  totalPosts:
                    type: integer
                  bySeries:
                    type: object
                    additionalProperties:
                      type: object
                      properties:
                        count:
                          type: integer
                        latest:
                          type: string
                  tags:
                    type: array
                    items:
                      type: string
                  generatedAt:
                    type: string
                    format: date-time
        '406':
          description: The Accept header excluded application/json.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Post:
      type: object
      required:
        - id
        - type
        - seriesLabel
        - seriesNumber
        - title
        - summary
        - url
      properties:
        id:
          type: string
          pattern: ^week-\d{2}$
          description: Stable post identifier, for example "week-44".
          examples:
            - week-44
        type:
          type: string
          enum:
            - research
            - practice
          description: Which of the two series the post belongs to.
        seriesLabel:
          type: string
          description: Human-facing series label, for example "Week 25" or "Article 20".
        seriesNumber:
          type: integer
          minimum: 1
          description: Position within its series.
        title:
          type: string
          description: Post title.
        summary:
          type: string
          description: One-paragraph summary as shown on the archive card.
        tags:
          type: array
          items:
            type: string
          description: Topic tags.
        readingTime:
          type:
            - string
            - 'null'
          description: Estimated reading time, for example "8 min read".
        datePublished:
          type:
            - string
            - 'null'
          format: date
          description: Publication date in ISO 8601.
        dateModified:
          type:
            - string
            - 'null'
          format: date-time
          description: Last modification timestamp in ISO 8601.
        wordCount:
          type: integer
          description: Word count of the post body.
        url:
          type: string
          format: uri
          description: Canonical HTML URL.
        markdownUrl:
          type: string
          format: uri
          description: Markdown representation of the same post.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - status
            - code
            - message
          properties:
            status:
              type: integer
              description: HTTP status code, repeated for clients that only read the body.
            code:
              type: string
              description: Stable machine-readable error code.
              examples:
                - resource_not_found
            message:
              type: string
              description: What went wrong, in one sentence.
            hint:
              type: string
              description: How to fix the request.
            path:
              type: string
              description: The path that produced the error.
            documentation:
              type: string
              format: uri
            specification:
              type: string
              format: uri
