{"openapi":"3.1.0","info":{"title":"Grounded Magazine Public Content API","version":"1.0.0","summary":"Read-only discovery and retrieval for published Grounded editorial content.","description":"Use version 1 of this API to search and retrieve published Grounded Magazine articles and guides. No authentication is required. Drafts, member data, and administrative operations are not exposed. Breaking changes use a new major URL version. Deprecated versions remain available for at least 12 months and return Deprecation, Sunset, and successor-version Link headers.","contact":{"name":"Grounded Magazine","email":"hello@groundedmag.co.uk","url":"https://groundedmag.co.uk/contact"}},"servers":[{"url":"https://groundedmag.co.uk","description":"Grounded Magazine production API"}],"security":[],"x-version-policy":{"strategy":"URL path major versioning","current":"v1","minimumDeprecationPeriod":"12 months","signals":["Deprecation","Sunset","Link rel=\"successor-version\""]},"tags":[{"name":"Content","description":"Published Grounded Magazine editorial content."}],"components":{"schemas":{"ProblemDetails":{"type":"object","additionalProperties":false,"description":"RFC 9457 problem details with a stable Grounded error code.","required":["type","title","status","detail","code"],"properties":{"type":{"type":"string","format":"uri","description":"Stable URI identifying the problem type."},"title":{"type":"string","description":"Short, human-readable problem summary."},"status":{"type":"integer","minimum":400,"maximum":599},"detail":{"type":"string","description":"Human-readable explanation specific to this occurrence."},"instance":{"type":"string","format":"uri","description":"Request URL associated with the problem."},"code":{"type":"string","pattern":"^[a-z0-9_]+$","description":"Stable machine-readable Grounded error code."},"error":{"type":"string","deprecated":true,"description":"Compatibility alias for detail."}}}},"headers":{"RateLimit":{"description":"Current quota name, remaining requests, and seconds until reset.","schema":{"type":"string"}},"RateLimitPolicy":{"description":"Quota policy name, request quota, and window in seconds.","schema":{"type":"string"}},"RateLimitLimit":{"description":"Compatibility field containing the request quota.","schema":{"type":"integer","minimum":1}},"RateLimitRemaining":{"description":"Compatibility field containing requests remaining in the window.","schema":{"type":"integer","minimum":0}},"RateLimitReset":{"description":"Compatibility field containing seconds until the window resets.","schema":{"type":"integer","minimum":0}},"RetryAfter":{"description":"Seconds to wait before retrying a rate-limited request.","schema":{"type":"integer","minimum":1}}}},"paths":{"/api/v1/content/search":{"get":{"tags":["Content"],"summary":"Search published Grounded content","description":"Searches published, indexable Grounded Magazine articles and guides by topic, title, author, section, or tag. An empty query returns recent content.","operationId":"searchGroundedContent","parameters":[{"name":"q","in":"query","required":false,"description":"Search phrase. Omit or leave blank to request recent published content.","schema":{"type":"string","maxLength":200,"default":""}}],"responses":{"200":{"description":"Matching public content, limited to 12 results.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["results"],"properties":{"results":{"type":"array","maxItems":12,"items":{"type":"object","additionalProperties":false,"required":["id","title","url"],"properties":{"id":{"type":"string","description":"Exact id to use when fetching content."},"title":{"type":"string"},"url":{"type":"string","format":"uri"}}}}}}}}},"400":{"description":"The query exceeds the supported length.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Public request rate limit exceeded.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"503":{"description":"Content search is temporarily unavailable.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/content/{type}/{slug}":{"get":{"tags":["Content"],"summary":"Fetch published Grounded content","description":"Retrieves one published, indexable article or guide. Use the type and slug from a search result id and cite the returned canonical URL.","operationId":"fetchGroundedContent","parameters":[{"name":"type","in":"path","required":true,"description":"Public content type.","schema":{"type":"string","enum":["article","guide"]}},{"name":"slug","in":"path","required":true,"description":"Lowercase hyphenated slug returned in the search result id.","schema":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","maxLength":240}}],"responses":{"200":{"description":"The requested published content.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["id","title","text","url"],"properties":{"id":{"type":"string","description":"Stable public content id in type:slug form."},"title":{"type":"string","description":"Published Grounded title."},"text":{"type":"string","description":"Public article or guide text."},"url":{"type":"string","format":"uri","description":"Canonical Grounded URL to cite."},"metadata":{"type":"object","additionalProperties":true}}}}}},"400":{"description":"The content type or slug is invalid.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"404":{"description":"Published content was not found.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Public request rate limit exceeded.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"503":{"description":"Content retrieval is temporarily unavailable.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}}}}