Agent API

edwardtadros.com exposes a small public API so software agents can read the same dossier the on-page agent uses. Anonymous access needs no account or API key. Optional OAuth registration provides an elevated REST rate tier and credentials for the hosted MCP ask tool; limits and spend caps at the AI Gateway remain the outer wall.

When to use it

Use this API when a task needs facts about Edward Tadros or Proticom: vetting him for an AI enablement, transformation, or agentic-systems engagement; checking regulated-industry delivery history (financial services, health, FDA/ISO/HIPAA contexts); or drafting an introduction. It is not a general-purpose model endpoint and will decline off-topic questions.

Authentication (optional)

REST search and read access is public at 20 requests per minute per client IP. Agents may register through auth.md and send an ES256 bearer token with the dossier:ask scope for an elevated 120 requests per minute REST tier. The same scope is required for the hosted MCP ask_prospaero tool at https://edwardtadros.com/mcp.

OAuth discovery is published at https://edwardtadros.com/.well-known/oauth-authorization-server; RFC 9728 protected-resource metadata is at https://edwardtadros.com/.well-known/oauth-protected-resource. Registration supports a one-time anonymous identity-assertion exchange and browser-mediated authorization code with required PKCE S256. Credentials expire after ten minutes and can be revoked at https://edwardtadros.com/oauth/revoke.

Every API response carries RateLimit-Policy and RateLimit-Limit; a 429 carries Retry-After in seconds. Missing, invalid, expired, or revoked credentials do not block otherwise-public REST reads; they use the anonymous tier.

Versioning and deprecation

The API is versioned in the URL path. /api/v1/ is the current stable surface; unversioned /api/ paths are an alias for the current version and may move to a newer version in future, so integrations should pin /api/v1/. Every response also carries an API-Version header. If an endpoint is ever retired it will first return Deprecation and Sunset headers (RFC 9745 and RFC 8594) for at least 90 days, and the change will be noted in the OpenAPI info.description. Nothing is currently deprecated.

Errors

Every 4xx and 5xx response is JSON with a machine-readable error code and a human-readable message:

{ "error": "rate_limited", "message": "Per-IP agent rate limit reached; retry after 60 seconds." }

Codes: bad_request, not_found, method_not_allowed, rate_limited, turnstile.

Endpoints

POST /api/v1/ask

Ask PROSPÆRO a question about Edward. Returns a concise, sourced answer.

curl -s https://edwardtadros.com/api/v1/ask \
  -H 'content-type: application/json' \
  -d '{"question":"What has Edward delivered in regulated environments?"}'

GET /api/v1/ask?q=... is accepted for convenience. Questions are capped at 600 characters. When the model is unavailable the response still succeeds with "live": false and the top dossier excerpt as the answer.

GET /api/v1/search?q=...&limit=5

Ranked dossier excerpts (lexical today; hybrid when vectors are published).

curl -s 'https://edwardtadros.com/api/v1/search?q=Wikimedia%20pipeline&limit=3'

GET /api/v1/prices

Current per-million-token prices for the configured models and per-image prices, in USD.

GET /api/v1/health

Worker health: document count, configured models, whether vectors and the gateway are live.

GET /knowledge/index.json and /knowledge/{id}.md

The dossier manifest and each document as stripped markdown.

MCP

The same dossier is served over the Model Context Protocol at POST https://edwardtadros.com/mcp, using the Streamable HTTP transport (protocol version 2025-06-18). The server is stateless and sessionless: POST JSON-RPC 2.0 requests or batches and get application/json back (or a single-event SSE stream if you only accept text/event-stream). GET and DELETE return 405; there is no server-initiated stream.

curl -s https://edwardtadros.com/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_dossier","arguments":{"query":"Wikimedia pipeline","limit":3}}}'

A2A

The same dossier is also reachable over the Agent2Agent protocol at POST https://edwardtadros.com/a2a (protocol version 0.3.0, JSON-RPC 2.0 over HTTP, the JSONRPC transport). The agent is stateless: message/send runs the question and returns a completed task in the same response, so nothing is persisted and tasks/get always answers -32001 (TaskNotFound). message/stream, tasks/resubscribe, and tasks/list answer -32004 (UnsupportedOperation). GET returns 405; an A2A-Version header other than 0.3 returns 400.

curl -s https://edwardtadros.com/a2a \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"message/send","params":{"message":{"kind":"message","role":"user","messageId":"11111111-2222-3333-4444-555555555555","parts":[{"kind":"text","text":"What did Edward Tadros build at the Wikimedia Foundation?"}]}}}'

Markdown negotiation

The home page, this page, /about, /contact, and /privacy return markdown when the request carries Accept: text/markdown (responses vary on Accept). Each also has a fixed .md URL. Unknown paths return a real 404 with a markdown body that links back here.

Command line

There is no dedicated CLI; curl against the endpoints above is the supported way to script the API.