mb.

Developers

Read it
with code

Everything on marcusboni.com.br that is meant to be read by a program rather than a person: the machine-readable files, the content-negotiation contract, and copy-pasteable curl for each one.

00 Scope

This is a personal portfolio and technical blog. Its API is public, read-only and unauthenticated: no private endpoints, no write operations, no published rate limit, and therefore no API keys to issue and no sandbox to provision. Every endpoint below is the production endpoint, which makes the API its own sandbox.

If you are an agent deciding whether this site answers your question, read /agent-instructions.md first. It says plainly what this site is and is not good for.

01 Quickstart

# The profile, as JSON
curl -s https://marcusboni.com.br/api/v1/profile

# The OpenAPI 3.1 description of every operation
curl -s https://marcusboni.com.br/openapi.json

# The site's own guide for language models
curl -s https://marcusboni.com.br/llms.txt

# Any page, as Markdown instead of HTML
curl -s -H 'Accept: text/markdown' https://marcusboni.com.br/

02 JSON API

Read-only representations of the same content the pages publish. The specification is OpenAPI 3.1; every operation carries a unique operationId, a description, typed parameters and a response schema, so the surface can be handed to a function-calling runtime unchanged. Discovery also goes through the RFC 9727 catalog at /.well-known/api-catalog.

Operation Endpoint Returns
getApiIndex GET /api/v1 The operation list and a link to the specification.
getProfile GET /api/v1/profile Identity, employer, location, contact channels, résumés.
listProjects GET /api/v1/projects Selected projects with year, stack and repository URL.
getExperience GET /api/v1/experience Current role and every client engagement, with sector and scope.
listTechnologies GET /api/v1/stack Technologies, grouped by frontend, backend, data and ops.
listPosts GET /api/v1/posts Published posts, newest first. Served live, so publishing needs no rebuild.
getPost GET /api/v1/posts/{slug} One post, including the Markdown it was authored in.

Errors

Every failure under /api/ is RFC 9457 application/problem+json — never an HTML error page — with a stable code and a hint naming the next thing to try.

{
  "type": "https://marcusboni.com.br/developers#error-not-found",
  "title": "Not found",
  "status": 404,
  "detail": "No published post has the slug \"ghost\". Drafts are not readable.",
  "instance": "/api/v1/posts/ghost",
  "code": "not_found",
  "hint": "GET https://marcusboni.com.br/api/v1/posts to list every published post and its slug."
}
Code Status When
not_found 404 No such endpoint, or no published post with that slug.
method_not_allowed 405 Anything but GET or HEAD. The API is read-only.
not_acceptable 406 Your Accept header rules out application/json.
upstream_unavailable 503 The content database is unreachable. Transient — retry.

Versioning and deprecation

The major version is in the URL path. /api/v1 is current; a breaking change ships as /api/v2, never as an edit to v1. Additive changes — a new endpoint, a new optional field — happen in place, so ignore unknown properties rather than failing on them.

A path being retired announces itself on its own responses, before it stops answering:

Header Spec Carries
Deprecation RFC 9745 When the path was deprecated, as @<unix-seconds>.
Sunset RFC 8594 When it stops responding, as an HTTP date.
Link RFC 8288 rel="deprecation", pointing at the explanation.

There are at least 180 days between the two dates. Nothing is deprecated today, so none of these headers appears on any current response — the mechanism is in place and tested so that the first deprecation is signalled rather than announced after the fact.

03 Markdown content negotiation

Every HTML document on this site is also available as Markdown from the same URL, following the acceptmarkdown.com convention. Blog posts are written in Markdown and stored that way, so their Markdown representation is the original source, not a conversion of the rendered HTML.

curl -sI -H 'Accept: text/markdown' https://marcusboni.com.br/
#  content-type: text/markdown; charset=utf-8
#  vary: Accept, Accept-Encoding
Request Accept Response
absent text/html — the default representation
*/* text/html
text/html text/html
text/markdown text/markdown; charset=utf-8
text/markdown;q=0.9, text/html;q=0.8 text/markdown — highest q wins
text/markdown;q=0 text/html — an explicit refusal of Markdown, not a 406
application/pdf 406 Not Acceptable, with a body listing both representations

Quality values and wildcard specificity are honoured; text/x-markdown and text/mdx are accepted as aliases. Every negotiated response carries Vary: Accept so a shared cache cannot hand an agent the HTML variant.

Negotiable paths: /, /blog, /blog/{slug}, /developers, and any unknown path — which answers 404 in both representations.

04 Machine-readable files

Endpoint Content type What it is
/openapi.json application/json OpenAPI 3.1 description of every API operation.
/.well-known/api-catalog application/linkset+json RFC 9727 discovery document pointing at the specification and the docs.
/llms.txt text/plain Condensed site guide in llmstxt.org format, including a "when to use this" section.
/llms-full.txt text/plain Full profile: bio, every project, every client engagement, the whole stack.
/agent-instructions.md text/markdown Best-fit tasks, how to call this site, and what not to infer from it.
/sitemap.xml application/xml Indexable URLs, generated per request so a new post is discoverable without a rebuild.
/rss.xml application/xml RSS 2.0 feed of published posts.
/robots.txt text/plain Crawl directives. Everything is allowed except /admin.
/marcus-boni-cv-pt.pdf application/pdf Résumé, Portuguese.
/marcus-boni-resume-en.pdf application/pdf Résumé, English.

05 Structured data

The home page carries a schema.org Person in JSON-LD; every blog post carries a BlogPosting, injected into the delivered HTML at the edge so it is present without executing JavaScript.

curl -s https://marcusboni.com.br/ | grep -A2 'application/ld+json'

06 HTTP behaviour

07 Reusing the content

The prose, résumés and images are © Marcus Boni. Quote and link freely, with attribution to marcusboni.com.br. Code in the linked GitHub repositories carries its own licence per repository.

Something wrong or missing on this page? Email mgalvaoboni@gmail.com.