{"openapi":"3.1.0","info":{"title":"agenticplug.ai API","version":"1.0.0","description":"Public HTTP API for agenticplug.ai. Includes an OAuth-protected Model Context Protocol (MCP) endpoint and public form/utility endpoints.","contact":{"name":"agenticplug.ai","url":"https://agenticplug.ai","email":"info@agenticplug.ai"}},"servers":[{"url":"https://agenticplug.ai"}],"paths":{"/api/mcp":{"post":{"operationId":"mcp","summary":"Model Context Protocol (Streamable HTTP) endpoint","description":"OAuth 2.1-protected MCP server exposing tools grounded in the agenticplug.ai knowledge base (AEO/GEO, agentic commerce protocols, services, methodology) and consultation tools (request a consultation and, where enabled, list open calendar times and book one). Discover auth via /.well-known/oauth-protected-resource/api/mcp (RFC 9728 path-suffixed metadata for this resource).","security":[{"oauth2":["mcp:read"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC / MCP response (JSON or text/event-stream)"},"401":{"description":"Missing or invalid bearer token. Returns WWW-Authenticate with resource_metadata."}}}},"/mcp":{"servers":[{"url":"https://scan.agenticplug.ai","description":"Agent Ready Report (Cloudflare Worker)"}],"post":{"operationId":"agentReadyReportMcp","summary":"Agent Ready Report: Model Context Protocol (Streamable HTTP) endpoint","description":"agenticplug.ai's website scanner, as an MCP server. No sign-in. Tools: scan_website (scan a public website for AI agent and AI search readiness) and explain_check (explain one check). Documentation: https://agenticplug.ai/agent-ready-report/docs","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC / MCP response (JSON or text/event-stream)"}}}},"/api/a2a":{"post":{"operationId":"a2a","summary":"A2A (Agent2Agent) JSON-RPC 2.0 endpoint","description":"Unauthenticated, read-only A2A agent (protocol 0.3.0). Supports the message/send method only; streaming and task history are not supported. Exposes the same capabilities as the MCP server: knowledge-base search, the A.G.E.N.T.I.C. framework, service lines, and published articles. Discover skills via /.well-known/agent-card.json.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["jsonrpc","method","params"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"oneOf":[{"type":"string"},{"type":"integer"}]},"method":{"type":"string","enum":["message/send"]},"params":{"type":"object","properties":{"skillId":{"type":"string","description":"Optional explicit skill: search_knowledge_base, get_agentic_framework, list_services, or list_blog_articles. Omit to route by keyword."},"message":{"type":"object","properties":{"role":{"type":"string"},"messageId":{"type":"string"},"parts":{"type":"array","items":{"type":"object"}}}}}}}}}}},"responses":{"200":{"description":"JSON-RPC 2.0 response. Success returns result as an agent message; protocol faults return an error object (-32700 parse, -32600 invalid request, -32601 method not found, -32602 invalid params, -32603 internal)."}}}},"/api/chat":{"post":{"operationId":"chat","summary":"FAQ chatbot (RAG, streaming)","description":"Streams a grounded answer from the agenticplug.ai wiki via pgvector retrieval. Browser-oriented; rate-limited and origin-restricted.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object"}},"sessionId":{"type":"string"},"consentToTranscriptStorage":{"type":"boolean"}},"required":["messages"]}}}},"responses":{"200":{"description":"UI message stream"},"429":{"description":"Rate limited"}}}},"/api/contact":{"post":{"operationId":"contact","summary":"Submit a contact / consultation request","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":200},"email":{"type":"string","format":"email","maxLength":200},"website":{"type":"string","maxLength":500},"company":{"type":"string","maxLength":200},"message":{"type":"string","minLength":5,"maxLength":5000}},"required":["name","email","message"]}}}},"responses":{"200":{"description":"Submitted"},"400":{"description":"Invalid form data"},"429":{"description":"Rate limited"}}}},"/api/consultation/availability":{"get":{"operationId":"consultationAvailability","summary":"Open times for a free 30-minute strategic consultation","description":"No sign-in. Reads the team's Google Calendar and returns every open slot in `slots` (`start` and `end` as ISO 8601, `display` readable in `timeZone`), plus `timeZone`, `hostTimeZone`, `durationMinutes`, `horizonDays`, `pastHorizon` and a Markdown rendering in `markdown` (which lists the first 40). Same data as the structuredContent of the get_consultation_availability tool on /api/mcp, and the same computation as on /book (WebMCP). POST the same fields plus a booking `reference` to list times for moving that booking (its own time is left out). Rate limited per IP.","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":14}},{"name":"from","in":"query","required":false,"description":"YYYY-MM-DD in the team's time zone.","schema":{"type":"string"}},{"name":"timeZone","in":"query","required":false,"description":"IANA zone for `display` and the Markdown rendering.","schema":{"type":"string"}}],"responses":{"200":{"description":"Open slots"},"400":{"description":"Invalid `from` date"},"429":{"description":"Rate limited"},"503":{"description":"Calendar unavailable"}}}},"/api/consultation/book":{"post":{"operationId":"bookConsultation","summary":"Book a free 30-minute strategic consultation","description":"Books an open slot and emails a standard calendar invitation to `email`; the message goes to the team, not into the invitation. One upcoming consultation per email address. Send a `retryKey` you generate: a retry with the same key returns the booking the first request made (with `replayed: true` and its `reference`) instead of a 409. Same booking as the book_consultation tool on /api/mcp and on /book (WebMCP). Rate limited per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"start":{"type":"string","description":"A slot `start` exactly as the availability endpoint returned it."},"name":{"type":"string","maxLength":200},"email":{"type":"string","format":"email","maxLength":200},"message":{"type":"string","minLength":5,"maxLength":5000},"company":{"type":"string","maxLength":200},"website":{"type":"string","maxLength":500},"timeZone":{"type":"string"},"retryKey":{"type":"string","minLength":16,"maxLength":128,"description":"A unique, unguessable value you generate for this booking (a UUID works). Reuse it only to retry the same request."}},"required":["start","name","email","message"]}}}},"responses":{"200":{"description":"Booked"},"400":{"description":"Invalid input or start time"},"409":{"description":"Slot unavailable, or this email already has a consultation booked"},"422":{"description":"This retryKey already booked a different time for this email"},"429":{"description":"Rate limited"},"503":{"description":"Calendar unavailable"}}}},"/api/consultation/booking":{"post":{"operationId":"consultationBooking","summary":"The booking a booking reference names","description":"Returns `start`, `end`, `email`, `meetUrl` when there is one, and `past` for the consultation a booking reference names. The reference is returned when a consultation is booked and is carried by the manage link in the invitation. POST so the reference stays out of URLs. Rate limited per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}},"required":["reference"]}}}},"responses":{"200":{"description":"Found"},"400":{"description":"Not a valid booking reference"},"404":{"description":"No active booking for this reference"},"429":{"description":"Rate limited"},"503":{"description":"Calendar unavailable"}}}},"/api/consultation/cancel":{"post":{"operationId":"cancelConsultation","summary":"Cancel a consultation by its booking reference","description":"Cancels the booking and has Google Calendar email the cancellation. Same operation as the cancel_consultation tool on /api/mcp and on /book (WebMCP). Rate limited per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"},"timeZone":{"type":"string"}},"required":["reference"]}}}},"responses":{"200":{"description":"Cancelled"},"400":{"description":"Not a valid booking reference"},"404":{"description":"No active booking for this reference"},"409":{"description":"The consultation has already started"},"429":{"description":"Rate limited"},"503":{"description":"Calendar unavailable"}}}},"/api/consultation/reschedule":{"post":{"operationId":"rescheduleConsultation","summary":"Move a consultation to another open time by its booking reference","description":"Books the new time first, then releases the old one; a new invitation is emailed and a new booking reference returned. `previousReleased` is false in the rare case the old booking could not be removed, and then both exist until the team removes it. At most 3 moves per booking. Same operation as the reschedule_consultation tool on /api/mcp and on /book (WebMCP). Rate limited per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"},"start":{"type":"string","description":"A slot `start` exactly as the availability endpoint returned it."},"timeZone":{"type":"string"}},"required":["reference","start"]}}}},"responses":{"200":{"description":"Rescheduled"},"400":{"description":"Invalid reference, start time, or the same time as now"},"404":{"description":"No active booking for this reference"},"409":{"description":"The new slot is not open, the consultation has already started, or it has been moved the maximum 3 times"},"429":{"description":"Rate limited"},"503":{"description":"Calendar unavailable"}}}},"/api/health":{"get":{"operationId":"health","summary":"Service health","responses":{"200":{"description":"Service is healthy"}}}}},"components":{"securitySchemes":{"oauth2":{"type":"oauth2","description":"OAuth 2.1. Agents may register anonymously at /agent/identity (auth.md agentic registration; the response carries an access token and an identity assertion that /oauth/token exchanges with the urn:ietf:params:oauth:grant-type:jwt-bearer grant), or self-register via Dynamic Client Registration (RFC 7591) at /oauth/register and use the client_credentials or authorization_code (PKCE) grant. Tokens from /agent/identity are revocable at /oauth/revoke (RFC 7009). Steps: /auth.md.","flows":{"clientCredentials":{"tokenUrl":"https://agenticplug.ai/oauth/token","scopes":{"mcp:read":"Access to the MCP tools, including the consultation tools"}},"authorizationCode":{"authorizationUrl":"https://agenticplug.ai/oauth/authorize","tokenUrl":"https://agenticplug.ai/oauth/token","scopes":{"mcp:read":"Access to the MCP tools, including the consultation tools"}}}}}}}