{
  "openapi": "3.1.0",
  "info": {
    "title": "Plant Grail Public API",
    "version": "1.0.0",
    "description": "Evidence-based houseplant care: diagnose problems, follow sourced protocols, and browse species-level guidance drawn from compiled botanical research. This OpenAPI document describes the public, unauthenticated JSON API. Private commerce and course endpoints are omitted. Rate limits use RFC RateLimit headers; HTTP 429 includes Retry-After.",
    "contact": {
      "name": "Plant Grail developer support",
      "email": "hello@plantgrail.com",
      "url": "https://plantgrail.com/developers/"
    },
    "license": {
      "name": "Content and API terms",
      "url": "https://plantgrail.com/privacy/"
    }
  },
  "servers": [
    {
      "url": "https://plantgrail.com",
      "description": "Plant Grail production"
    }
  ],
  "tags": [
    {
      "name": "Health",
      "description": "Service liveness for agents and monitors."
    },
    {
      "name": "Plants",
      "description": "Species index derived from the Plant Grail knowledge base."
    },
    {
      "name": "Articles",
      "description": "Public article feed for learning surfaces and agents."
    },
    {
      "name": "Discovery",
      "description": "Machine-readable specs and docs."
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "Health"
        ],
        "summary": "Service health",
        "description": "Returns a JSON health document so agents can confirm the Plant Grail origin is reachable without executing JavaScript.",
        "responses": {
          "200": {
            "description": "Service is reachable.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "service",
                    "timestamp"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "service": {
                      "type": "string",
                      "example": "plantgrail"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/plants": {
      "get": {
        "operationId": "listPlants",
        "tags": [
          "Plants"
        ],
        "summary": "List tracked plants",
        "description": "Lists unique plants in the knowledge base with pagination. No authentication. Use this for function-calling plant lookup.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum plants to return (1–500).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Number of plants to skip.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated plant list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "data",
                    "metadata"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "metadata": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        },
                        "offset": {
                          "type": "integer"
                        }
                      }
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "slug",
                          "common_name"
                        ],
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "common_name": {
                            "type": "string"
                          },
                          "scientific_name": {
                            "type": "string"
                          },
                          "grail_entry_count": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid pagination parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message",
                        "resolution"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "NOT_FOUND"
                        },
                        "message": {
                          "type": "string"
                        },
                        "resolution": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/articles.json": {
      "get": {
        "operationId": "listArticles",
        "tags": [
          "Articles"
        ],
        "summary": "List published articles",
        "description": "Returns a newest-first JSON feed of Plant Grail articles (title, slug, description, tags, URL). Bodies are omitted for a lightweight agent payload.",
        "responses": {
          "200": {
            "description": "Article feed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "articles",
                    "total"
                  ],
                  "properties": {
                    "total": {
                      "type": "integer"
                    },
                    "articles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "type",
                          "slug",
                          "title",
                          "url"
                        ],
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "article",
                              "pseo"
                            ]
                          },
                          "slug": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "subject": {
                            "type": "string"
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "pubDate": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "url": {
                            "type": "string"
                          },
                          "heroImage": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiDocument",
        "tags": [
          "Discovery"
        ],
        "summary": "OpenAPI 3.1 specification",
        "description": "Machine-readable Plant Grail API surface for LLM function calling and API clients.",
        "responses": {
          "200": {
            "description": "OpenAPI document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "resolution"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "NOT_FOUND"
              },
              "message": {
                "type": "string"
              },
              "resolution": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}