{
  "name": "portfolio.dylansg0318.workers.dev",
  "description": "A read-only API over the same facts the site renders. Every record carries `page`, the address of the page it describes.",
  "endpoints": [
    {
      "method": "GET",
      "path": "/api/dylan",
      "description": "Who this is: role, employer, the one-sentence summary in either register, location, links.",
      "params": [
        {
          "name": "view",
          "description": "Which register the summary is written in. The site has two; the pages show both.",
          "one_of": [
            "plain",
            "engineer"
          ]
        },
        {
          "name": "fields",
          "description": "Comma-separated keys to return instead of the whole record. `page` always comes back."
        }
      ],
      "source": "src/lib/site.ts"
    },
    {
      "method": "GET",
      "path": "/api/work",
      "description": "Every top-level project, newest and most important first. Subsystems are reached through their parent.",
      "params": [
        {
          "name": "category",
          "description": "Filter to one shelf: work, tool or game. What the thing is, not what it was built with.",
          "one_of": [
            "work",
            "tool",
            "game"
          ]
        },
        {
          "name": "fields",
          "description": "Comma-separated keys to return instead of the whole record. `page` always comes back."
        }
      ],
      "source": "src/content/projects/*"
    },
    {
      "method": "GET",
      "path": "/api/work/{id}",
      "description": "One project in full: the contract (problem, what was unique, what I learned), the numbers, the parts.",
      "params": [
        {
          "name": "id",
          "description": "A project id from GET /api/work, or a subsystem id such as internal-erp/repricing.",
          "one_of": []
        },
        {
          "name": "fields",
          "description": "Comma-separated keys to return instead of the whole record. `page` always comes back."
        }
      ],
      "source": "src/content/projects/{id}"
    },
    {
      "method": "GET",
      "path": "/api/experience",
      "description": "The path here — the stops, the jobs, education and certifications.",
      "params": [
        {
          "name": "since",
          "description": "Only jobs that started in this year or later.",
          "one_of": [
            "2021",
            "2022",
            "2025"
          ]
        },
        {
          "name": "fields",
          "description": "Comma-separated keys to return instead of the whole record. `page` always comes back."
        }
      ],
      "source": "src/lib/site.ts"
    },
    {
      "method": "GET",
      "path": "/api/resume",
      "description": "The one-page résumé: summary, experience with bullets, projects, skills, education. The same facts the printed PDF carries.",
      "params": [
        {
          "name": "format",
          "description": "json returns the record; html and pdf return the record with `page` pointing at that version.",
          "one_of": [
            "json",
            "html",
            "pdf"
          ]
        },
        {
          "name": "fields",
          "description": "Comma-separated keys to return instead of the whole record. `page` always comes back."
        }
      ],
      "source": "src/lib/site.ts"
    },
    {
      "method": "GET",
      "path": "/api/away-from-work",
      "description": "What I do when I am not at a keyboard, and the first thing I ever shipped, which is still playable.",
      "params": [
        {
          "name": "playable",
          "description": "When true, `page` is the playable game rather than its write-up."
        },
        {
          "name": "fields",
          "description": "Comma-separated keys to return instead of the whole record. `page` always comes back."
        }
      ],
      "source": "src/lib/site.ts · src/content/projects/galaxy-defense"
    },
    {
      "method": "POST",
      "path": "/api/contact",
      "description": "Send a message. Until mail delivery is configured the route answers 503 with a mailto link, and the console opens it.",
      "params": [
        {
          "name": "from",
          "description": "Your email, so I can reply."
        },
        {
          "name": "message",
          "description": "The message. Ten characters or more."
        }
      ],
      "source": "src/pages/api/contact.ts"
    }
  ],
  "fields": "Any GET accepts ?fields=a,b to return a subset of keys; `page` always comes back.",
  "page": "https://portfolio.dylansg0318.workers.dev/"
}