{
  "openapi": "3.1.0",
  "info": {
    "title": "tobis.vision — Tobi Moccagatta content API",
    "version": "1.0.0",
    "summary": "Read-only access to the content behind tobis.vision, plus the site's machine-readable discovery files.",
    "description": "The portfolio of Tobi Moccagatta, Creative Developer at basement.studio.\n\nEvery operation is a GET, every response is public, and no credentials exist to send. Writes go through the CMS admin and are not part of this description.\n\nStart at `/api/v1/site`. One call returns the identity, the contact address, current availability, every page with its markdown twin, and every endpoint below — enough to decide whether a second call is worth making.\n\n## Versioning\n\n- Versions live in the URL path. `/api/v1/…` is the current major and the one to integrate against.\n- `/api/…` is an unversioned alias of whatever major is current — convenient for a one-off read, wrong for anything that has to keep working.\n- A breaking change ships as a new major at a new path. The old path keeps working through its deprecation window.\n- Adding a field, an endpoint or an optional parameter is not breaking, and happens without a version bump.\n\n## Deprecation\n\n- A retiring version answers with `Deprecation` (RFC 9745) carrying the date the deprecation took effect, and `Sunset` (RFC 8594) carrying the date it stops answering.\n- Both come with `Link: <…>; rel=\"deprecation\"` pointing at the notice.\n- The window between the two is at least six months.\n- Nothing is deprecated today, so neither header is being sent.\n\n## Rate limits\n\n- 120 requests per 60 seconds per client, on GET and HEAD.\n- Every response carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`, and the structured-field `RateLimit` and `RateLimit-Policy` the current draft defines. Read either.\n- Over the limit is `429` with `Retry-After` in seconds.\n- Counters are held per server instance, so the effective limit across a fleet is higher than the number quoted. Pace against the headers, not the number.\n\nHuman-readable index of the same surface: https://tobis.vision/developers\nAgent instructions: https://tobis.vision/agents.md",
    "x-api-major": 1,
    "x-unversioned-alias": "/api",
    "contact": {
      "name": "Tobi Moccagatta",
      "email": "contact@tobis.vision",
      "url": "https://tobis.vision"
    },
    "license": {
      "name": "All rights reserved",
      "identifier": "LicenseRef-All-Rights-Reserved"
    }
  },
  "servers": [
    {
      "url": "https://tobis.vision",
      "description": "Production. Paths below are the versioned ones; `/api/…` answers identically today and is not pinned."
    }
  ],
  "tags": [
    {
      "name": "Content",
      "description": "The documents the pages are built from."
    },
    {
      "name": "Discovery",
      "description": "Files whose whole purpose is to be found and read by a machine."
    },
    {
      "name": "Pages",
      "description": "The site's own pages, as markdown."
    }
  ],
  "paths": {
    "/api/v1/site": {
      "get": {
        "operationId": "getSite",
        "summary": "Everything about this site and the person behind it",
        "description": "One call, no parameters: identity, location, contact address, availability, what to use this source for and what not to, every page with its markdown twin, every other endpoint, and the rate-limit policy. Start here rather than crawling.",
        "tags": [
          "Content"
        ],
        "responses": {
          "200": {
            "description": "The site profile.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Site"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/works": {
      "get": {
        "operationId": "listWorks",
        "summary": "List published work",
        "description": "Filtering uses Payload's query syntax — `where[year][greater_than]=2023`, `where[kind][equals]=client`.",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Documents per page. `0` returns every document.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 10
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page number.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Field to sort by. Prefix with `-` to reverse, comma-separate for tie-breaks — e.g. `order,-year`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "depth",
            "in": "query",
            "required": false,
            "description": "How many levels of related documents to resolve. `0` leaves relationships as ids; `2` inlines the media a work points at.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10,
              "default": 2
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of works.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkList"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/works/{id}": {
      "get": {
        "operationId": "getWork",
        "summary": "Fetch one work by id",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Numeric document id, as returned by `/api/works`.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "depth",
            "in": "query",
            "required": false,
            "description": "How many levels of related documents to resolve. `0` leaves relationships as ids; `2` inlines the media a work points at.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10,
              "default": 2
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The work.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Work"
                }
              }
            }
          },
          "404": {
            "description": "No such document. The body is a Payload error envelope, not the site's HTML 404.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/media": {
      "get": {
        "operationId": "listMedia",
        "summary": "List images and video",
        "description": "Every asset carries `alt`, and images carry `width`/`height`. Videos are stored as separate mp4/webm/poster documents referenced by a work's media blocks.",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Documents per page. `0` returns every document.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 10
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page number.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Field to sort by. Prefix with `-` to reverse, comma-separate for tie-breaks — e.g. `order,-year`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "depth",
            "in": "query",
            "required": false,
            "description": "How many levels of related documents to resolve. `0` leaves relationships as ids; `2` inlines the media a work points at.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10,
              "default": 2
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of media documents.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaList"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/media/{id}": {
      "get": {
        "operationId": "getMedia",
        "summary": "Fetch one media document by id",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The media document.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Media"
                }
              }
            }
          },
          "404": {
            "description": "No such document. The body is a Payload error envelope, not the site's HTML 404.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notes": {
      "get": {
        "operationId": "listNotes",
        "summary": "List published notes",
        "description": "The write-ups, newest first. Each carries the URL of its page and of its markdown twin; the prose itself comes from the single-note operation.",
        "tags": [
          "Content"
        ],
        "responses": {
          "200": {
            "description": "Every published note, without its body.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NoteList"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notes/{slug}": {
      "get": {
        "operationId": "getNote",
        "summary": "Fetch one note, prose included",
        "description": "`body` is the post as markdown — the same text the page renders, with its JSX removed.",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "URL segment, as returned by the list operation.",
            "schema": {
              "type": "string",
              "enum": [
                "alpha-to-coverage-foliage-atlases",
                "real-time-gi-that-just-brightened-the-walls",
                "mcp-server-that-writes-webgpu-shaders",
                "msaa-breaks-gtao-on-webgpu",
                "three-js-bloom-jimenez-dual-filter"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The note.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Note"
                }
              }
            }
          },
          "404": {
            "description": "No such document. The body is a Payload error envelope, not the site's HTML 404.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/experiments": {
      "get": {
        "operationId": "listExperiments",
        "summary": "List the live WebGPU experiments",
        "description": "Each entry is a page that is a running scene rather than a document. The markdown twin describes what it does; the URL is where it runs.",
        "tags": [
          "Content"
        ],
        "responses": {
          "200": {
            "description": "Every published experiment.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExperimentList"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/graphql": {
      "get": {
        "operationId": "getGraphqlSchema",
        "summary": "Describe the GraphQL endpoint, and print its schema",
        "description": "The same content as the REST operations above, generated by the CMS. A `GET` returns this descriptor with the schema as SDL in `sdl`; queries go to the same address as a `POST` of `{ query, variables }`.\n\nIntrospection is enabled, complexity is capped at 1000, and every mutation in the schema is refused — there is no login this API accepts.",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "The endpoint, its limits and its schema.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GraphQL"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/globals/home": {
      "get": {
        "operationId": "getHomeGlobal",
        "summary": "Home page copy",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "depth",
            "in": "query",
            "required": false,
            "description": "How many levels of related documents to resolve. `0` leaves relationships as ids; `2` inlines the media a work points at.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10,
              "default": 2
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The home global.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Home"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/globals/about": {
      "get": {
        "operationId": "getAboutGlobal",
        "summary": "The bio, as Lexical rich text",
        "description": "For the same text already rendered, read https://tobis.vision/about.md.",
        "tags": [
          "Content"
        ],
        "responses": {
          "200": {
            "description": "The about global.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/About"
                }
              }
            }
          },
          "429": {
            "description": "Over the limit. Retry after the number of seconds in `Retry-After`. Counters are per server instance, so this can arrive earlier or later than 120 requests would suggest.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed in the window. Currently 120.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit": {
                "description": "The same figures as a structured-field dictionary — `default;r=119;t=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The policy in force — `default;q=120;w=60`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-API-Version": {
                "description": "Major version that answered.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "summary": "The site in one plain-text file — pages, selected work, experiments, contact.",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "The site in one plain-text file — pages, selected work, experiments, contact.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "operationId": "getSitemapXml",
        "summary": "Every published URL.",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "Every published URL.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/robots.txt": {
      "get": {
        "operationId": "getRobotsTxt",
        "summary": "Crawler policy. Retrieval and training crawlers are both allowed.",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "Crawler policy. Retrieval and training crawlers are both allowed.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/agents.md": {
      "get": {
        "operationId": "getAgentsMd",
        "summary": "When to use this site, when not to, and how to call it.",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "When to use this site, when not to, and how to call it.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiDocument",
        "summary": "This document",
        "description": "The OpenAPI 3.1 description of every operation listed here, built from the same route registry the site renders from.",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "This document.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenApiDocument"
                }
              }
            }
          }
        }
      }
    },
    "/{page}.md": {
      "get": {
        "operationId": "getPageMarkdown",
        "summary": "A page as markdown",
        "description": "The same documents are served at each page's own URL when the request carries `Accept: text/markdown`, per acceptmarkdown.com. Those responses set `Vary: Accept, Accept-Encoding`.\n\nExample: `https://tobis.vision/about.md`.",
        "tags": [
          "Pages"
        ],
        "parameters": [
          {
            "name": "page",
            "in": "path",
            "required": true,
            "description": "Page path without its leading slash.",
            "schema": {
              "type": "string",
              "enum": [
                "index",
                "experiments",
                "works",
                "about",
                "contact",
                "privacy",
                "developers",
                "notes",
                "experiments/grass",
                "experiments/critters",
                "experiments/lpv",
                "experiments/bip",
                "experiments/fluid",
                "notes/alpha-to-coverage-foliage-atlases",
                "notes/real-time-gi-that-just-brightened-the-walls",
                "notes/mcp-server-that-writes-webgpu-shaders",
                "notes/msaa-breaks-gtao-on-webgpu",
                "notes/three-js-bloom-jimenez-dual-filter"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page, as markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "No such page. The body is a markdown 404 listing every page that does exist.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Work": {
        "type": "object",
        "description": "One project.",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "slug": {
            "type": "string",
            "description": "URL segment. Lowercase, hyphenated."
          },
          "year": {
            "type": "integer"
          },
          "summary": {
            "type": "string",
            "description": "One or two sentences, written to stand alone out of context."
          },
          "body": {
            "anyOf": [
              {
                "type": "object",
                "description": "Lexical rich text, as stored by Payload. `root.children` is an array of block nodes; text lives on `text` nodes underneath. The rendered markdown of the same content is available from the page's markdown representation.",
                "properties": {
                  "root": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string"
                      },
                      "children": {
                        "type": "array",
                        "items": {
                          "type": "object"
                        }
                      }
                    }
                  }
                },
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "basement",
              "client",
              "personal"
            ],
            "description": "Who authored it: studio work, freelance for a client, or personal."
          },
          "client": {
            "type": "object",
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "stack": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "id": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "name"
              ]
            }
          },
          "role": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "id": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "name"
              ]
            }
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "required": [
                "label",
                "url"
              ]
            }
          },
          "media": {
            "type": "array",
            "description": "Blocks of `blockType: \"image\"` or `\"video\"`. The first is what the card shows. Related media are ids at `depth=0` and inlined documents from `depth=1`.",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "badge": {
            "type": [
              "string",
              "null"
            ]
          },
          "span": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "half",
              "full",
              null
            ]
          },
          "order": {
            "type": [
              "integer",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "title",
          "slug",
          "year",
          "summary",
          "kind"
        ]
      },
      "WorkList": {
        "type": "object",
        "description": "Payload's paginated list envelope.",
        "properties": {
          "docs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Work"
            }
          },
          "totalDocs": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "pagingCounter": {
            "type": "integer"
          },
          "hasPrevPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          },
          "prevPage": {
            "type": [
              "integer",
              "null"
            ]
          },
          "nextPage": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "docs",
          "totalDocs",
          "limit",
          "page",
          "totalPages"
        ]
      },
      "Media": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "alt": {
            "type": "string",
            "description": "What it shows, in a sentence."
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "filename": {
            "type": [
              "string",
              "null"
            ]
          },
          "mimeType": {
            "type": [
              "string",
              "null"
            ]
          },
          "filesize": {
            "type": [
              "integer",
              "null"
            ]
          },
          "width": {
            "type": [
              "integer",
              "null"
            ]
          },
          "height": {
            "type": [
              "integer",
              "null"
            ]
          },
          "thumbnailURL": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "alt"
        ]
      },
      "MediaList": {
        "type": "object",
        "description": "Payload's paginated list envelope.",
        "properties": {
          "docs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Media"
            }
          },
          "totalDocs": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "pagingCounter": {
            "type": "integer"
          },
          "hasPrevPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          },
          "prevPage": {
            "type": [
              "integer",
              "null"
            ]
          },
          "nextPage": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "docs",
          "totalDocs",
          "limit",
          "page",
          "totalPages"
        ]
      },
      "Home": {
        "type": "object",
        "properties": {
          "greeting": {
            "type": "string",
            "description": "The page's h1."
          },
          "intro": {
            "type": "string"
          },
          "availability": {
            "type": "string"
          },
          "availableLead": {
            "type": "string"
          },
          "services": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "id": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "name"
              ]
            }
          },
          "featured": {
            "type": "array",
            "description": "Works shown in the home carousel, in order. Ids at `depth=0`, documents above it.",
            "items": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "$ref": "#/components/schemas/Work"
                }
              ]
            }
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "greeting",
          "intro",
          "availability"
        ]
      },
      "About": {
        "type": "object",
        "properties": {
          "bio": {
            "type": "object",
            "description": "Lexical rich text, as stored by Payload. `root.children` is an array of block nodes; text lives on `text` nodes underneath. The rendered markdown of the same content is available from the page's markdown representation.",
            "properties": {
              "root": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string"
                  },
                  "children": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  }
                }
              }
            },
            "additionalProperties": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "bio"
        ]
      },
      "Site": {
        "type": "object",
        "description": "The whole of this site's own facts, in one document. Derived from the route registry and the site config, so it cannot disagree with the pages.",
        "properties": {
          "name": {
            "type": "string"
          },
          "alternateNames": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "jobTitle": {
            "type": "string"
          },
          "seniority": {
            "type": "string"
          },
          "workingSince": {
            "type": "string",
            "description": "`YYYY-MM` of the first professional work."
          },
          "summary": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "employer": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "sameAs": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "name",
              "url"
            ]
          },
          "location": {
            "type": "object",
            "properties": {
              "city": {
                "type": "string"
              },
              "country": {
                "type": "string",
                "description": "ISO 3166-1 alpha-2."
              },
              "utcOffset": {
                "type": "string"
              }
            },
            "required": [
              "city",
              "country",
              "utcOffset"
            ]
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "contact": {
            "type": "object",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              },
              "contactType": {
                "type": "string"
              },
              "page": {
                "type": "string",
                "format": "uri"
              },
              "markdown": {
                "type": "string",
                "format": "uri"
              },
              "channels": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "label",
                    "url"
                  ]
                }
              }
            },
            "required": [
              "email",
              "page"
            ]
          },
          "availability": {
            "type": "object",
            "properties": {
              "open": {
                "type": "boolean"
              },
              "forms": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "offer": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  }
                }
              }
            },
            "required": [
              "open",
              "forms"
            ]
          },
          "knowsAbout": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "awards": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "profiles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "agentGuidance": {
            "type": "object",
            "description": "The prose of llms.txt and /agents.md, as arrays — when this source is worth calling, when it is not, what it can back up, and how to read it.",
            "properties": {
              "useWhen": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "doNotUseWhen": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "credentials": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "howToCall": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "useWhen",
              "doNotUseWhen",
              "credentials",
              "howToCall"
            ]
          },
          "pages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "markdown": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "required": [
                "path",
                "url",
                "title",
                "description",
                "markdown"
              ]
            }
          },
          "discovery": {
            "type": "object",
            "description": "Every machine-readable file, by name.",
            "properties": {
              "llmsTxt": {
                "type": "string",
                "format": "uri"
              },
              "agentsMd": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "sitemap": {
                "type": "string",
                "format": "uri"
              },
              "robots": {
                "type": "string",
                "format": "uri"
              },
              "developers": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "llmsTxt",
              "agentsMd",
              "openapi",
              "sitemap",
              "robots"
            ]
          },
          "api": {
            "type": "object",
            "properties": {
              "major": {
                "type": "integer"
              },
              "versionedPrefix": {
                "type": "string"
              },
              "unversionedPrefix": {
                "type": "string"
              },
              "readOnly": {
                "type": "boolean"
              },
              "authentication": {
                "type": "string",
                "enum": [
                  "none"
                ]
              },
              "endpoints": {
                "type": "object",
                "additionalProperties": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "rateLimit": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "limit": {
                    "type": "integer"
                  },
                  "windowSeconds": {
                    "type": "integer"
                  },
                  "policy": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "limit",
                  "windowSeconds"
                ]
              },
              "versioning": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "deprecation": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "major",
              "versionedPrefix",
              "readOnly",
              "authentication",
              "endpoints",
              "rateLimit"
            ]
          }
        },
        "required": [
          "name",
          "jobTitle",
          "summary",
          "url",
          "location",
          "contact",
          "availability",
          "pages",
          "discovery",
          "api"
        ]
      },
      "Note": {
        "type": "object",
        "description": "One write-up.",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "updated": {
            "type": "string",
            "format": "date"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "path": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "markdown": {
            "type": "string",
            "format": "uri"
          },
          "body": {
            "type": "string",
            "description": "The post as markdown. Present on the single-note operation only."
          }
        },
        "required": [
          "slug",
          "title",
          "description",
          "date",
          "tags",
          "path",
          "url",
          "markdown"
        ]
      },
      "NoteList": {
        "type": "object",
        "description": "Newest first. Bodies are omitted.",
        "properties": {
          "docs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Note"
            }
          },
          "totalDocs": {
            "type": "integer"
          }
        },
        "required": [
          "docs",
          "totalDocs"
        ]
      },
      "Experiment": {
        "type": "object",
        "description": "One live WebGPU scene.",
        "properties": {
          "slug": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "markdown": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "stack": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "slug",
          "path",
          "url",
          "title",
          "description",
          "stack"
        ]
      },
      "ExperimentList": {
        "type": "object",
        "properties": {
          "docs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Experiment"
            }
          },
          "totalDocs": {
            "type": "integer"
          }
        },
        "required": [
          "docs",
          "totalDocs"
        ]
      },
      "GraphQL": {
        "type": "object",
        "description": "What the GraphQL endpoint is, what it refuses, and its schema.",
        "properties": {
          "endpoint": {
            "type": "string",
            "format": "uri"
          },
          "method": {
            "type": "string",
            "enum": [
              "POST"
            ]
          },
          "contentType": {
            "type": "string"
          },
          "readOnly": {
            "type": "boolean"
          },
          "authentication": {
            "type": "string",
            "enum": [
              "none"
            ]
          },
          "introspection": {
            "type": "string",
            "enum": [
              "enabled"
            ]
          },
          "maxComplexity": {
            "type": "integer"
          },
          "rateLimit": {
            "type": "object",
            "properties": {
              "limit": {
                "type": "integer"
              },
              "windowSeconds": {
                "type": "integer"
              },
              "note": {
                "type": "string"
              }
            },
            "required": [
              "limit",
              "windowSeconds"
            ]
          },
          "sampleQuery": {
            "type": "string"
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "documentation": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          },
          "sdl": {
            "type": [
              "string",
              "null"
            ],
            "description": "The schema in SDL. Null only if it could not be printed, in which case `sdlUnavailable` says so and introspection is the fallback."
          },
          "sdlUnavailable": {
            "type": "string"
          }
        },
        "required": [
          "endpoint",
          "method",
          "readOnly",
          "authentication",
          "introspection",
          "maxComplexity",
          "sdl"
        ]
      },
      "OpenApiDocument": {
        "type": "object",
        "description": "An OpenAPI 3.1 description — this document's own shape.",
        "properties": {
          "openapi": {
            "type": "string"
          },
          "info": {
            "type": "object",
            "additionalProperties": true
          },
          "servers": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "paths": {
            "type": "object",
            "additionalProperties": true
          },
          "components": {
            "type": "object",
            "additionalProperties": true
          },
          "externalDocs": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "openapi",
          "info",
          "paths",
          "components"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "message"
              ]
            }
          }
        },
        "required": [
          "errors"
        ]
      }
    }
  },
  "externalDocs": {
    "description": "Developer resources for tobis.vision",
    "url": "https://tobis.vision/developers"
  }
}
