api
This site has a public API.
The site serves its own content over a small JSON API. Reads are public and need no key, responses carry permissive CORS headers so they work from a browser, and every route returns the same error envelope. It runs in the same Node process as the pages you are reading, on the cluster described on the infrastructure page.
base url
https://nordbye.iterror envelope
{
"error": {
"status": 401,
"message": "missing or invalid API key"
}
}The whole surface is also published as an OpenAPI 3.1 document, generated from the same definitions as this page, so it can be imported straight into Postman, Bruno or a client generator.
reference
Endpoints.
7 routes. Start at the discovery index if you would rather read it as JSON.
/api/healthpublicLiveness probe.
Unversioned and always dynamic, so it reflects the running process rather than a build-time cache. This is the target Kubernetes uses for its probes.
- Cache policy
- cache-control: no-store
request
curl -s https://nordbye.it/api/healthresponse
{
"status": "ok"
}/api/v1publicDiscovery index.
The front door: a machine-readable map of every endpoint, generated from the same source as this page. Static, because the map only changes when the code does.
- Cache policy
- cache-control: public, max-age=60
request
curl -s https://nordbye.it/api/v1response
{
"name": "Morten Nordbye — portfolio API",
"version": "v1",
"docs": "https://nordbye.it/api",
"openapi": "https://nordbye.it/api/v1/openapi.json",
"endpoints": [
{
"method": "GET",
"path": "/api/health",
"desc": "Liveness probe."
}
],
"notes": "Reads are public. Writes require an API key."
}/api/v1/openapi.jsonpublicOpenAPI 3.1 document.
The whole surface as a spec you can import into Postman, Bruno, Swagger UI or a client generator. Generated from the same endpoint definitions that render this page, so it cannot drift from the routes it describes.
- Cache policy
- cache-control: public, max-age=60
request
curl -s https://nordbye.it/api/v1/openapi.jsonresponse
{
"openapi": "3.1.0",
"info": {
"title": "Morten Nordbye — portfolio API",
"version": "v1"
},
"servers": [
{
"url": "https://nordbye.it"
}
],
"paths": {
"/api/health": {
"get": {
"operationId": "getHealth"
}
}
}
}/api/v1/profilepublicIdentity, certifications, skills and socials.
Served straight from the content modules that render the site itself, so the API and the pages can never disagree. Refreshed on each deploy.
- Cache policy
- cache-control: public, max-age=60
request
curl -s https://nordbye.it/api/v1/profileresponse
{
"name": "Morten Nordbye",
"role": "Cloud Engineer & Architect",
"location": "Oslo, Norway",
"url": "https://nordbye.it",
"summary": "Cloud engineer working on automated, secure infrastructure…",
"socials": [
{
"label": "GitHub",
"href": "https://github.com/mortennordbye"
}
],
"certifications": [
{
"title": "CKA: Certified Kubernetes Administrator",
"issuer": "The Linux Foundation",
"date": "Jan 2024"
}
],
"skills": [
{
"label": "Kubernetes",
"level": 80,
"group": "platform"
}
]
}/api/v1/infrapublicLive Talos cluster status and 30-day history.
A CronJob in the cluster writes a status ConfigMap every five minutes; it is mounted into the pod and read fresh per request. When the file is not mounted the route falls back to a baked snapshot and marks it with a source field. This is what drives the infrastructure page.
- Cache policy
- cache-control: public, max-age=30
request
curl -s https://nordbye.it/api/v1/infraresponse
{
"generatedAt": "2026-07-19T08:05:03Z",
"build": "0.0.80",
"argocd": {
"sync": "Synced",
"health": "Healthy"
},
"nodes": {
"ready": 6,
"total": 6
},
"versions": {
"kubernetes": "v1.34.0",
"talos": "v1.11.6"
},
"cert": {
"notAfter": "2026-09-25T11:41:28Z"
},
"history": [
{
"d": "2026-07-16",
"ok": 286,
"total": 288
}
]
}/api/v1/blogpublicLatest five posts from blog.nordbye.it.
Parses the Hugo RSS feed and revalidates hourly, which keeps the blog origin from being hit once per request. Returns 502 with the standard error envelope when the feed is unreachable.
- Cache policy
- cache-control: revalidated hourly
request
curl -s https://nordbye.it/api/v1/blogresponse
{
"source": "https://blog.nordbye.it/index.xml",
"count": 5,
"posts": [
{
"title": "Tuning Azure WAF Without Paying Log Analytics Prices",
"url": "https://blog.nordbye.it/blog/lawless-waf/",
"publishedAt": "2026-07-16T00:00:00.000Z",
"published": "Thu, 16 Jul 2026 00:00:00 +0000"
}
]
}/api/v1/echoapi keyAuthenticated write example.
A reference write that proves the authenticated POST seam without persisting anything. The key is compared in constant time, and writes are refused outright when no key is configured on the server. Real stateful writes build on this pattern and add a datastore.
- Cache policy
- cache-control: no-store
request
curl -s -X POST https://nordbye.it/api/v1/echo \
-H 'authorization: Bearer $PORTFOLIO_API_KEY' \
-H 'content-type: application/json' \
-d '{"hello":"world"}'response
{
"ok": true,
"echo": {
"hello": "world"
}
}