{"openapi":"3.1.0","info":{"title":"StudioMeyer Public API","version":"1.0.0","description":"Public website endpoints, no API key required. JSON bodies required for POST; quote accepts an empty object. Major versions use /api/v{major}; breaking changes receive a new major-version URL. Deprecations announce the replacement in documentation and response headers; a sunset date is published only when scheduled. The separate authenticated API Platform is documented at /api/openapi.","contact":{"email":"hello@studiomeyer.io"}},"servers":[{"url":"https://studiomeyer.io"}],"security":[],"paths":{"/api/v1/memory/purchase":{"get":{"summary":"Read new Memory Pro or Team subscription purchase information: current price, localized purchase link and account-management link. Account status is unknown; existing paid subscribers should use account management first. This request starts no checkout session or payment. The user starts checkout and confirms payment themselves.","operationId":"get_purchase","responses":{"200":{"description":"JSON response","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"product":{"type":"object","properties":{"slug":{"type":"string","const":"memory"},"name":{"type":"string"}},"required":["slug","name"],"additionalProperties":false},"plan":{"type":"object","properties":{"id":{"type":"string","enum":["pro","team"]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"locale":{"type":"string","enum":["de","en","es"]},"purchaseType":{"type":"string","const":"new_subscription"},"accountStatus":{"type":"string","const":"unknown"},"amountMinor":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Published price in the currency's minor unit, read from the current product catalog."},"currency":{"type":"string","enum":["EUR","USD"]},"interval":{"type":"string","const":"month"},"purchaseUrl":{"type":"string","pattern":"^https:\\/\\/studiomeyer\\.io\\/(?:de|en|es)\\/services\\/memory#memory-(?:pro|team)$","description":"HTTPS StudioMeyer purchase-page URL at the selected plan's real anchor; not a payment-session URL."},"managementUrl":{"type":"string","pattern":"^https:\\/\\/studiomeyer\\.io\\/(?:de|en|es)\\/portal\\/memory$","description":"Localized Memory account-management page for existing paid subscribers. Account status was not checked."},"requiresUserConfirmation":{"type":"boolean","const":true},"paymentInitiated":{"type":"boolean","const":false},"nextStep":{"type":"string","description":"The user reviews the selected plan, starts the existing checkout and confirms payment themselves."}},"required":["product","plan","locale","purchaseType","accountStatus","amountMinor","currency","interval","purchaseUrl","managementUrl","requiresUserConfirmation","paymentInitiated","nextStep"],"additionalProperties":false}}}},"400":{"description":"Invalid request or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded; observe Retry-After and rate-limit headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"parameters":[{"name":"plan","in":"query","required":true,"schema":{"type":"string","enum":["pro","team"],"description":"Existing paid Memory plan: pro or team."}},{"name":"locale","in":"query","required":false,"schema":{"description":"Purchase-page language. HTTP defaults to de; browser tools use the current page language when omitted.","type":"string","enum":["de","en","es"],"default":"de"}}],"description":"Read-only new-subscription purchase information. Account status is unknown; existing paid subscribers should use managementUrl first. Unknown, repeated or invalid parameters return 400. A user starts checkout and confirms payment; this request creates no session and initiates no payment.","x-request-schema":{"type":"object","properties":{"plan":{"type":"string","enum":["pro","team"],"description":"Existing paid Memory plan: pro or team."},"locale":{"default":"de","description":"Purchase-page language. HTTP defaults to de; browser tools use the current page language when omitted.","type":"string","enum":["de","en","es"]}},"required":["plan"],"additionalProperties":false}}},"/api/v1/portfolio":{"get":{"summary":"Browse the three demo sites (fictional showcase businesses, not customers) filtered by industry and style.","operationId":"get_portfolio","responses":{"200":{"description":"JSON response","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"agency":{"type":"string"},"total":{"type":"integer"},"demos":{"type":"integer"},"filters":{"type":"object","properties":{"industry":{"type":"string"},"style":{"type":"string"}},"required":["industry","style"]},"projects":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"type":{"const":"demo"},"category":{"type":"string"},"url":{"type":"string","format":"uri"},"heroImage":{"type":"string","format":"uri"},"mobileImage":{"type":"string","format":"uri"},"tech":{"type":"array","items":{"type":"string"}}},"required":["name","slug","type","category","url","heroImage","mobileImage","tech"]}},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Cursor for the next page, or null when this is the final page."},"_note":{"type":"string"}},"required":["agency","total","demos","filters","projects","next_cursor","_note"]}}}},"400":{"description":"Invalid request or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded; observe Retry-After and rate-limit headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"parameters":[{"name":"industry","in":"query","required":false,"schema":{"type":"string","enum":["immobilien","gastronomie","hotellerie","alle"]}},{"name":"style","in":"query","required":false,"schema":{"type":"string","enum":["premium","modern","alle"]}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","description":"Opaque cursor from the previous response's next_cursor. Omit for the first page."}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size from 1 to 100.","default":20}}]}},"/api/v1/services":{"get":{"summary":"Full service catalog with capabilities and delivery models.","operationId":"get_services","responses":{"200":{"description":"JSON response","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"agency":{"type":"string"},"website":{"type":"string","format":"uri"},"language":{"type":"string","enum":["de","en","es"]},"languageNote":{"type":"string"},"positioning":{"type":"string"},"webdesign":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":"string"},"packages":{"type":"array","items":{"type":"object","required":["id","name","price","priceType","delivery"],"properties":{"id":{"type":"string","enum":["fundament","wachstum","individuell"]},"name":{"type":"string"},"price":{"type":"string"},"priceType":{"type":"string","enum":["fixed","from"]},"delivery":{"type":"string"},"fixedPrice":{"type":"string"}}}},"payment":{"type":"string"},"scope":{"type":"string"},"care":{"type":"object","required":["name","terms","covers"],"properties":{"name":{"type":"string"},"terms":{"type":"string"},"covers":{"type":"string"}}}},"required":["url","description","packages","payment","scope","care"]},"growth":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":"string"},"pricing":{"type":"string"}},"required":["url","description","pricing"]},"aiConnector":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"description":{"type":"string"},"standard":{"type":"string"},"pro":{"type":"string"},"note":{"type":"string"}},"required":["name","url","description","standard","pro","note"]},"automationAndAgents":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":"string"},"pricing":{"type":"string"}},"required":["url","description","pricing"]},"localAiSystems":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":"string"},"pricing":{"type":"string"}},"required":["url","description","pricing"]},"mcpServers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"plans":{"type":"string"}},"required":["name","url","plans"]}},"forAgencies":{"type":"object","properties":{"whiteLabel":{"type":"boolean"},"description":{"type":"string"},"contact":{"type":"string"}},"required":["whiteLabel","description","contact"]},"industries":{"type":"array","items":{"type":"string"}},"contact":{"type":"object","properties":{"email":{"type":"string","format":"email"},"contactPage":{"type":"string","format":"uri"},"introCall":{"type":"string"},"consultationApi":{"type":"string","format":"uri"}},"required":["email","contactPage","introCall","consultationApi"]}},"required":["agency","website","language","languageNote","positioning","webdesign","growth","aiConnector","automationAndAgents","localAiSystems","mcpServers","forAgencies","industries","contact"]}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded; observe Retry-After and rate-limit headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"parameters":[{"name":"lang","in":"query","required":false,"description":"de or es (case-insensitive prefix); otherwise en. Quote body lang takes precedence.","schema":{"type":"string"}}]}},"/api/v1/quote":{"post":{"summary":"Get the published web design packages, prices, payment terms, scope, StudioMeyer Care and next contact step. Non-binding; project requirements do not calculate a price and there is no fixed page count.","operationId":"post_quote","responses":{"200":{"description":"JSON response","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["agency","language","request","packages","payment","scope","care","aiReady","note","nextStep"],"properties":{"agency":{"type":"string"},"language":{"type":"string","enum":["de","en","es"]},"request":{"type":"object","required":["projectType","notes"],"properties":{"projectType":{"type":["string","null"],"enum":["website","webshop","webapp","redesign",null]},"notes":{"type":["string","null"]}}},"packages":{"type":"array","items":{"type":"object","required":["id","name","price","priceType","delivery"],"properties":{"id":{"type":"string","enum":["fundament","wachstum","individuell"]},"name":{"type":"string"},"price":{"type":"string"},"priceType":{"type":"string","enum":["fixed","from"]},"delivery":{"type":"string"},"fixedPrice":{"type":"string"}}}},"payment":{"type":"string"},"scope":{"type":"string"},"care":{"type":"object","required":["name","terms","covers"],"properties":{"name":{"type":"string"},"terms":{"type":"string"},"covers":{"type":"string"}}},"aiReady":{"type":"string"},"note":{"type":"string"},"nextStep":{"type":"object","required":["action","contactPage","email","api","a2aSkill"],"properties":{"action":{"type":"string"},"contactPage":{"type":"string","format":"uri"},"email":{"type":"string","format":"email"},"api":{"type":"string","format":"uri"},"a2aSkill":{"type":"string"}}}}}}}},"400":{"description":"Invalid request or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"413":{"description":"Request body too large (32KB limit)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded; observe Retry-After and rate-limit headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectType":{"type":"string","enum":["website","webshop","webapp","redesign"],"description":"Optional project type; does not change package prices."},"pages":{"anyOf":[{"type":"string","maxLength":10},{"type":"number"}],"description":"Legacy compatibility field, ignored; no fixed page count."},"features":{"type":"string","maxLength":500,"description":"Legacy alias for notes; notes takes precedence."},"notes":{"type":"string","maxLength":500,"description":"Optional project context, returned with the request."},"lang":{"type":"string","maxLength":5,"description":"Package language: de or es (case-insensitive prefix); otherwise en. Overrides query lang."}}}}}},"parameters":[{"name":"lang","in":"query","required":false,"description":"de or es (case-insensitive prefix); otherwise en. Quote body lang takes precedence.","schema":{"type":"string"}}]}},"/api/v1/case-study":{"get":{"summary":"Write-ups of the three demo sites with challenge, solution and tech stack, each marked as a demo.","operationId":"get_case_study","responses":{"200":{"description":"JSON response","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"agency":{"type":"string"},"caseStudy":{"type":"object","properties":{"industry":{"type":"string"},"project":{"type":"string"},"client":{"type":"string"},"type":{"type":"string","enum":["customer","demo"]},"challenge":{"type":"string"},"solution":{"type":"string"},"results":{"type":"array","items":{"type":"object","properties":{"metric":{"type":"string"},"value":{"type":"string"},"estimated":{"type":"boolean"}},"required":["metric","value","estimated"]}},"tech":{"type":"array","items":{"type":"string"}},"url":{"type":"string","format":"uri"},"testimonial":{"type":"string"}},"required":["industry","project","client","type","challenge","solution","results","tech","url"]},"_note":{"type":"string"}},"required":["agency","caseStudy"]},{"type":"object","properties":{"agency":{"type":"string"},"total":{"type":"integer"},"_note":{"type":"string"},"caseStudies":{"type":"array","items":{"type":"object","properties":{"industry":{"type":"string"},"project":{"type":"string"},"client":{"type":"string"},"type":{"type":"string","enum":["customer","demo"]},"challenge":{"type":"string"},"solution":{"type":"string"},"results":{"type":"array","items":{"type":"object","properties":{"metric":{"type":"string"},"value":{"type":"string"},"estimated":{"type":"boolean"}},"required":["metric","value","estimated"]}},"tech":{"type":"array","items":{"type":"string"}},"url":{"type":"string","format":"uri"},"testimonial":{"type":"string"}},"required":["industry","project","client","type","challenge","solution","results","tech","url"]}},"availableIndustries":{"type":"array","items":{"type":"string"}}},"required":["agency","total","_note","caseStudies","availableIndustries"]}]}}}},"404":{"description":"Unknown industry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded; observe Retry-After and rate-limit headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"parameters":[{"name":"industry","in":"query","required":false,"schema":{"type":"string","enum":["immobilien","gastronomie","hotellerie"]}}]}},"/api/v1/consultation":{"post":{"summary":"Request a free introductory consultation. This is a non-binding inquiry; it does not book an appointment.","operationId":"post_consultation","responses":{"200":{"description":"JSON response","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"const":true},"id":{"type":"string"},"message":{"type":"string"},"consultation":{"type":"object","properties":{"type":{"type":"string"},"duration":{"type":"string"},"format":{"type":"string"},"topic":{"type":"string"},"responseTime":{"type":"string"}},"required":["type","duration","format","topic","responseTime"]}},"required":["success","message"]}}}},"400":{"description":"Invalid request or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"409":{"description":"Idempotency key conflicts with another body (IDEMPOTENCY_CONFLICT), or the original inquiry remains incomplete (IDEMPOTENCY_IN_PROGRESS). Keep the same key and body when checking an incomplete inquiry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Retry-After":{"description":"Seconds to wait before checking an in-progress inquiry with the same key and body. Present for IDEMPOTENCY_IN_PROGRESS.","schema":{"type":"integer","minimum":1}}}},"413":{"description":"Request body too large (32KB limit)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded; observe Retry-After and rate-limit headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Consultation request could not be processed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Use a random UUID for one intended inquiry and reuse the same key and JSON body when retrying. Completed results are replayed while their inbox entry is retained. A changed body returns 409 IDEMPOTENCY_CONFLICT. An unfinished request returns 409 IDEMPOTENCY_IN_PROGRESS with Retry-After; retry with the same key and body, and contact support if it remains incomplete. Never automatically switch keys to retry an incomplete inquiry. Requests without a key keep their existing behavior.","schema":{"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9_-]{16,128}$","description":"Use a random UUID for one intended inquiry and reuse the same key and JSON body when retrying. Completed results are replayed while their inbox entry is retained. A changed body returns 409 IDEMPOTENCY_CONFLICT. An unfinished request returns 409 IDEMPOTENCY_IN_PROGRESS with Retry-After; retry with the same key and body, and contact support if it remains incomplete. Never automatically switch keys to retry an incomplete inquiry. Requests without a key keep their existing behavior."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"email":{"type":"string","format":"email","maxLength":320,"description":"A real deliverable address; reserved example domains are rejected."},"phone":{"type":"string","maxLength":30},"topic":{"type":"string","maxLength":500},"website":{"type":"string","maxLength":0,"description":"Honeypot; omit or leave empty."}},"required":["name","email"]}}}}}},"/api/v1/validate-webmcp":{"get":{"summary":"Validate a website's WebMCP and agents.json implementation against the spec.","operationId":"get_validate_webmcp","responses":{"200":{"description":"JSON response","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"agency":{"type":"string"},"apiVersion":{"type":"string"},"validation":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"passed":{"type":"integer"},"errors":{"type":"integer"},"warnings":{"type":"integer"},"total":{"type":"integer"},"valid":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"check":{"type":"string"},"valid":{"type":"boolean"},"detail":{"type":"string"},"severity":{"type":"string","enum":["error","warning","info"]}},"required":["check","valid","detail","severity"]}}},"required":["url","passed","errors","warnings","total","valid","results"]},"spec":{"type":"object","properties":{"agentsJson":{"type":"string","format":"uri"},"agentCard":{"type":"string","format":"uri"},"webmcp":{"type":"string","format":"uri"}},"required":["agentsJson","agentCard","webmcp"]}},"required":["agency","apiVersion","validation","spec"]}}}},"400":{"description":"Invalid request or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded; observe Retry-After and rate-limit headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","example":"studiomeyer.io"}}]}},"/api/v1/generate-agents-json":{"post":{"summary":"Generate agents.json and agent-card.json for any business. Returns ready-to-deploy files.","operationId":"post_generate_agents_json","responses":{"200":{"description":"JSON response","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"agency":{"type":"string"},"generatedFor":{"type":"string"},"businessType":{"type":"string"},"files":{"type":"object","properties":{"agents.json":{"type":"object","properties":{"schema_version":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"url":{"type":"string","format":"uri"},"contact":{"type":"object","properties":{"email":{"type":"string"}},"required":["email"]},"tools":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"endpoint":{"type":"string"},"method":{"type":"string"},"parameters":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string"},"description":{"type":"string"},"required":{"type":"boolean"},"enum":{"type":"array","items":{"type":"string"}}},"required":["type","description"]}}},"required":["name","description","endpoint","method","parameters"]}},"capabilities":{"type":"object","properties":{"webmcp":{"type":"boolean"},"a2a":{"type":"boolean"},"languages":{"type":"array","items":{"type":"string"}}},"required":["webmcp","a2a","languages"]}},"required":["schema_version","name","description","url","contact","tools","capabilities"]},"agent-card.json":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"supportedInterfaces":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"protocolBinding":{"type":"string"},"protocolVersion":{"type":"string"}},"required":["url","protocolBinding","protocolVersion"]}},"provider":{"type":"object","properties":{"organization":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["organization","url"]},"version":{"type":"string"},"capabilities":{"type":"object","properties":{"streaming":{"type":"boolean"},"pushNotifications":{"type":"boolean"}},"required":["streaming","pushNotifications"]},"defaultInputModes":{"type":"array","items":{"type":"string"}},"defaultOutputModes":{"type":"array","items":{"type":"string"}},"skills":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"inputModes":{"type":"array","items":{"type":"string"}},"outputModes":{"type":"array","items":{"type":"string"}}},"required":["id","name","description","tags","inputModes","outputModes"]}}},"required":["name","description","supportedInterfaces","provider","version","capabilities","defaultInputModes","defaultOutputModes","skills"]}},"required":["agents.json","agent-card.json"]},"implementation":{"type":"object","properties":{"note":{"type":"string"},"agentCard":{"type":"string"},"nextjs":{"type":"string"},"wordpress":{"type":"string"},"static":{"type":"string"}},"required":["note","agentCard","nextjs","wordpress","static"]},"upgrade":{"type":"object","properties":{"message":{"type":"string"},"pricing":{"type":"string"},"includes":{"type":"array","items":{"type":"string"}},"contact":{"type":"string"}},"required":["message","pricing","includes","contact"]}},"required":["agency","generatedFor","businessType","files","implementation","upgrade"]}}}},"400":{"description":"Invalid request or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"413":{"description":"Request body too large (32KB limit)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded; observe Retry-After and rate-limit headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"businessName":{"type":"string","minLength":1,"maxLength":200,"description":"Public name of the business."},"businessType":{"type":"string","description":"Business category used to choose the generated tool template.","enum":["restaurant","immobilien","handwerk","corporate","ecommerce"]},"url":{"type":"string","format":"uri","maxLength":500,"description":"Canonical HTTPS website URL to place in the generated files."},"description":{"type":"string","maxLength":1000,"description":"Short factual description of the business and its offer."},"language":{"type":"string","maxLength":5,"description":"Language code for generated labels; defaults to de.","default":"de"}},"required":["businessName","businessType"]}}}}}},"/api/v1/docs":{"get":{"summary":"Public API documentation and discovery links","operationId":"get_docs","responses":{"200":{"description":"API documentation","headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"baseUrl":{"type":"string","format":"uri"},"description":{"type":"string"},"endpoints":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"method":{"type":"string"},"description":{"type":"string"},"example":{"type":"string"},"parameters":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string"},"optional":{"type":"boolean"},"required":{"type":"boolean"},"values":{"type":"array","items":{"type":"string"}},"enum":{"type":"array","items":{"type":"string"}},"anyOf":{"type":"array","items":{"$ref":"#/components/schemas/JsonSchema"}},"default":{"type":"string"},"example":{"type":"string"},"description":{"type":"string"},"minLength":{"type":"integer"},"maxLength":{"type":"integer"},"minimum":{"type":"integer"},"maximum":{"type":"integer"},"format":{"type":"string"},"pattern":{"type":"string"}},"required":[]}},"headers":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string"},"optional":{"type":"boolean"},"required":{"type":"boolean"},"values":{"type":"array","items":{"type":"string"}},"enum":{"type":"array","items":{"type":"string"}},"anyOf":{"type":"array","items":{"$ref":"#/components/schemas/JsonSchema"}},"default":{"type":"string"},"example":{"type":"string"},"description":{"type":"string"},"minLength":{"type":"integer"},"maxLength":{"type":"integer"},"minimum":{"type":"integer"},"maximum":{"type":"integer"},"format":{"type":"string"},"pattern":{"type":"string"}},"required":[]}},"body":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string"},"optional":{"type":"boolean"},"required":{"type":"boolean"},"values":{"type":"array","items":{"type":"string"}},"enum":{"type":"array","items":{"type":"string"}},"anyOf":{"type":"array","items":{"$ref":"#/components/schemas/JsonSchema"}},"default":{"type":"string"},"example":{"type":"string"},"description":{"type":"string"},"minLength":{"type":"integer"},"maxLength":{"type":"integer"},"minimum":{"type":"integer"},"maximum":{"type":"integer"},"format":{"type":"string"},"pattern":{"type":"string"}},"required":[]}},"responseSchema":{"$ref":"#/components/schemas/JsonSchema"}},"required":["path","method","description","example"]}},"discovery":{"type":"object","properties":{"agentsJson":{"type":"string","format":"uri"},"agentCard":{"type":"string","format":"uri"},"openApi":{"type":"string","format":"uri"}},"required":["agentsJson","agentCard","openApi"]},"rateLimit":{"type":"string"},"contact":{"type":"string"},"versioning":{"type":"object","properties":{"majorVersion":{"type":"integer"},"urlPattern":{"type":"string"},"breakingChanges":{"type":"string"},"deprecation":{"type":"string"}},"required":["majorVersion","urlPattern","breakingChanges","deprecation"]}},"required":["name","version","baseUrl","description","endpoints","discovery","rateLimit","contact","versioning"]}}}},"405":{"description":"HTTP method not supported by this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Allow":{"description":"Supported HTTP methods.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"RateLimit":{"description":"Remaining requests and seconds to reset for the named policy (HTTP RateLimit draft).","schema":{"type":"string"}},"RateLimit-Policy":{"description":"Named policy, request quota and window in seconds (HTTP RateLimit draft).","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Request quota for the policy.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Reset time as Unix epoch seconds.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"ErrorResponse":{"type":"object","properties":{"success":{"const":false},"code":{"type":"string"},"message":{"type":"string"},"resolution":{"type":"string"},"error":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}},"retryAfterMs":{"type":"number"},"availableIndustries":{"type":"array","items":{"type":"string"}},"example":{"type":"string","format":"uri"}},"required":["success","code","message","resolution","error"]},"JsonSchema":{"description":"A JSON Schema document, with schema keywords as properties.","type":"object","additionalProperties":true}}}}