{"openapi":"3.1.0","info":{"title":"Apuna Core API bus","version":"0.1.0","description":"A unified, self-describing surface over Apuna's free, key-less endpoints plus a thin Open-Meteo weather proxy. Every response uses one envelope: { ok, service, data | error, meta }. Public, per-IP rate limited.","contact":{"name":"Apuna","url":"https://apuna.dev"}},"servers":[{"url":"https://apuna.dev"}],"tags":[{"name":"data","description":"Free read-only data endpoints"},{"name":"compute","description":"Cost-bearing endpoints (free models via Requesty) — rate-gated harder"}],"paths":{"/core/v1/weather":{"get":{"operationId":"weather","summary":"Current weather for a location","description":"Thin proxy to Open-Meteo (no API key). Returns current temperature, humidity and precipitation for the given coordinates. (Rate limit: 60 req/min/IP.)","tags":["data"],"responses":{"200":{"description":"Success envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreOk"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}}},"parameters":[{"name":"lat","in":"query","required":true,"description":"Latitude (-90..90)","schema":{"type":"string","example":"51.5"}},{"name":"lon","in":"query","required":true,"description":"Longitude (-180..180)","schema":{"type":"string","example":"9.9"}}]}},"/core/v1/stats":{"get":{"operationId":"stats","summary":"Site transparency counters","description":"Read-only KV counters: bots blocked and legitimate form submissions. (Rate limit: 60 req/min/IP.)","tags":["data"],"responses":{"200":{"description":"Success envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreOk"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}}}}},"/core/v1/bots-blocked":{"get":{"operationId":"bots-blocked","summary":"Count of automated submissions blocked","description":"Read-only tally of bot submissions stopped at the form layer (honeypot + Turnstile). (Rate limit: 60 req/min/IP.)","tags":["data"],"responses":{"200":{"description":"Success envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreOk"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}}}}},"/core/v1/transparency":{"get":{"operationId":"transparency","summary":"Data-source registry","description":"The typed manifest of every data source the site uses, grouped by pillar. First-party metadata, no secrets. (Rate limit: 60 req/min/IP.)","tags":["data"],"responses":{"200":{"description":"Success envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreOk"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}}}}},"/core/v1/plants":{"get":{"operationId":"plants","summary":"Office-plant watering log (read-only)","description":"Public read of the office-plant watering log. Writes are team-only via Cloudflare Access and are not exposed on the bus. (Rate limit: 60 req/min/IP.)","tags":["data"],"responses":{"200":{"description":"Success envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreOk"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}}}}},"/core/v1/commodity":{"post":{"operationId":"commodity","summary":"Commodity intelligence from a company URL","description":"Fetches a company's public site, safety-screens the text, extracts the top purchasing commodities, and attaches delayed market quotes. Decision-support only. Cost-bearing (free model via Requesty). (Rate limit: 10 req/min/IP.)","tags":["compute"],"responses":{"200":{"description":"Success envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreOk"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"url":"https://example-manufacturer.com"}}}}}},"/core/v1/hardware":{"post":{"operationId":"hardware","summary":"Hardware bring-up how-to, grounded in docs","description":"Resolves a component, fetches documentation, and grounds every wiring/config/code claim in what was found. Cost-bearing (free model via Requesty). (Rate limit: 10 req/min/IP.)","tags":["compute"],"responses":{"200":{"description":"Success envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreOk"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoreError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"component":"MFRC522 RFID reader","docUrl":""}}}}}}},"components":{"schemas":{"CoreOk":{"type":"object","required":["ok","service","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"service":{"type":"string"},"data":{"description":"Service-specific payload"},"meta":{"type":"object","properties":{"via":{"type":"string"},"upstream":{"type":"string"}}}}},"CoreError":{"type":"object","required":["ok","service","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"service":{"type":"string"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"meta":{"type":"object"}}}}}}