Whether the API is serving traffic, which version is current, and whether it is deprecated.
curl https://jordandalton.com/api/v1/healthEverything on this site is readable by a program: a public JSON API, an MCP server, markdown versions of every page, and a set of discovery files. No signup, no API key, no OAuth dance.
Versioned in the path. A breaking change ships as /api/v2 and v1 keeps working alongside it.
Every endpoint is public and read-mostly. No API key, no bearer token, no CSRF token. Send Accept: application/json and go.
Every response carries RateLimit-Limit, -Remaining, -Reset, and RateLimit-Policy. A 429 adds Retry-After.
Whether the API is serving traffic, which version is current, and whether it is deprecated.
curl https://jordandalton.com/api/v1/healthEvery service with price, duration, and landing page, plus availability and payment terms.
curl https://jordandalton.com/api/v1/servicesPublished articles, newest first, with slug, title, description, date, and canonical URL.
curl https://jordandalton.com/api/v1/articlesOne article by slug, including the full markdown body.
curl https://jordandalton.com/api/v1/articles/how-much-does-an-ai-consultant-costSubmit a build day booking request. Jordan gets an SMS and replies by email, normally within 24 hours.
curl -X POST https://jordandalton.com/api/v1/bookings \
-H "Content-Type: application/json" \
-d '{
"name": "Ada Lovelace",
"email": "ada@example.com",
"brief": "Ship an internal dashboard on top of our Postgres warehouse."
}'Request and response shapes for all of these are typed in the OpenAPI 3.1 spec. Every operation has a unique operationId and a described, typed response schema, so the spec drops straight into an LLM function-calling setup.
Every 4xx and 5xx response is application/problem+json (RFC 9457). Branch on code, show error.message to a human, and act on error.hint. This holds for HTML paths too: request a missing page with Accept: application/json and you get the same object.
{
"type": "https://jordandalton.com/docs#error-validation_failed",
"title": "Validation Failed",
"status": 422,
"detail": "The email field is required.",
"instance": "/api/v1/bookings",
"code": "validation_failed",
"message": "The email field is required.",
"error": {
"code": "validation_failed",
"message": "The email field is required.",
"hint": "One or more fields failed validation. The \"errors\" object maps each field to its problems. Fix those fields and retry.",
"fields": { "email": ["The email field is required."] }
},
"documentation_url": "https://jordandalton.com/docs",
"errors": { "email": ["The email field is required."] }
}| code | status | what to do |
|---|---|---|
| not_found | 404 | Nothing exists at that path or slug. List valid slugs with listArticles. |
| method_not_allowed | 405 | The path exists but not for that method. Check the spec. |
| validation_failed | 422 | One or more fields are wrong. The errors object names each one. |
| rate_limited | 429 | Quota exceeded. Wait the seconds in Retry-After, then retry. |
| server_error | 500 | Failure on our side. Retry once with backoff. |
Every endpoint is under /api/v1/. Additive changes (a new field, a new endpoint) ship into v1. Anything that would break an existing integration ships as /api/v2/ instead, and v1 keeps serving.
When a version is scheduled for removal, its responses carry a Deprecation header (RFC 9745) and a Sunset header (RFC 8594) with the removal date, at least six months ahead. GET /api/v1/health reports the same thing as deprecated and sunset fields, so a poller never has to read headers. v1 is current and is not deprecated.
https://jordandalton.com/mcp speaks MCP over Streamable HTTP with no authentication. Add it to Claude, ChatGPT, Cursor, or any MCP client:
{
"mcpServers": {
"jordan-dalton": {
"type": "http",
"url": "https://jordandalton.com/mcp"
}
}
}Send Accept: text/markdown to any content page and you get clean markdown instead of HTML. Responses declare Vary: Accept, so a cache in front of the site cannot hand you the wrong variant. Missing pages return a real 404 with a markdown body that points back here.
curl -H "Accept: text/markdown" https://jordandalton.com/servicesThere is no separate CLI to install. The API is plain HTTP with no auth, so curl and jq are the CLI:
# every service and its price
curl -s https://jordandalton.com/api/v1/services | jq '.data[] | {name, price}'
# the latest article, as markdown
curl -s https://jordandalton.com/api/v1/articles \
| jq -r '.data[0].slug' \
| xargs -I{} curl -s https://jordandalton.com/api/v1/articles/{} \
| jq -r '.data.markdown'If an endpoint you need does not exist, or a response shape is wrong, email jordan@daltonsolutions.com and it usually gets fixed the same week. More on who is behind this at /about, and the ways to reach a human at /contact.