# info.description
Machine-readable catalog of the portfolio's agent-facing HTTP and MCP surfaces.

## Versioning
This API is version `v1` (see `info.version`). **Every response carries an `Api-Version: v1` header** — read it to confirm the contract in use. Clients MAY send an `Api-Version: v1` request header (accepted and echoed). Non-breaking additions (new fields/endpoints) ship under the same `v1`; a breaking change bumps to `v2`. Agents should treat responses as forward-compatible (tolerate unknown fields).

## Deprecation policy
A version or endpoint being retired is signaled in advance via: (1) an HTTP `Deprecation: true` header on responses, and (2) an RFC 8594 `Sunset` header giving the removal date — published at least **6 months** before that date. A `Link: rel="successor-version"` header points to the replacement when one exists. Watch `Deprecation`/`Sunset` headers to migrate ahead of removal.

## Rate limiting
Responses include RFC 9427 rate-limit headers (`RateLimit-Policy`, `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`). A `429` response additionally includes `Retry-After`. Key-protected endpoints reflect the per-key daily quota in these headers.

## Authentication
Discovery surfaces are open. The portfolio read API (`/functions/readPortfolio`) requires a self-serve API key (`/functions/issueApiKey`) as `Authorization: Bearer <api_key>` with the `portfolio:read` scope.

# components.parameters.ApiVersion.description
API version. Current and default is v1; echoed on every response.

# components.headers.Deprecation.description
Present (value `true`) only when this endpoint/version is deprecated.

# components.headers.Sunset.description
RFC 8594 removal date (HTTP-date) for a deprecated endpoint/version.

# components.headers.RateLimit-Remaining.description
RFC 9427 remaining requests in the window.

# components.headers.Retry-After.description
Seconds to wait before retrying after a 429.

# components.schemas.Error.properties.error.properties.hint.example
Check the available resources for this endpoint.

# components.responses.Error.description
Structured JSON error with a code, a human-readable message, and a resolution hint.

# components.securitySchemes.oauth2.description
OAuth 2.0 scoped access. Portfolio surfaces are read-only; access is currently open, but agents that present a scoped token should request the least-privilege scope listed on each operation.

# components.securitySchemes.oauth2.flows.clientCredentials.scopes.portfolio:read
Read portfolio case studies, about, and featured work.

# components.securitySchemes.oauth2.flows.clientCredentials.scopes.contact:read
Read contact details (email and WhatsApp).

# components.securitySchemes.oauth2.flows.clientCredentials.scopes.discovery:read
Read agent/API discovery metadata (catalogs, skills, capability documents).

# paths./functions/agentDiscovery.get.description
Agent capability document with content negotiation (JSON default; markdown/HTML via ?format or Accept).

# paths./api/mcp.get.description
Read-only Model Context Protocol server (portfolio + contact tools).

# paths./functions/agentSkills.get.description
Discovery index of agent skills; ?skill=<name> returns a single skill as markdown.

# paths./functions/apiCatalog.get.description
RFC 9264 linkset of the site's APIs. ?format=openapi returns the OpenAPI 3.0 spec.

# paths./functions/issueApiKey.post.description
Self-serve registration — no contact form. Body: { name, owner_email, scopes?, sandbox? }. Returns a free (100 req/day, 30-day) or sandbox (30 req/day, 7-day) API key shown once.

# paths./functions/readPortfolio.get.description
Returns a portfolio page as JSON. Requires `Authorization: Bearer <api_key>` with the `portfolio:read` scope; enforces the key's daily quota and emits RFC 9427 rate-limit headers plus `Api-Version`.