{
  "openapi": "3.0.3",
  "info": {
    "title": "FishPulse",
    "version": "1.0.0",
    "description": "FishPulse scores fishing and outdoor conditions 0-100 for any GPS location using real-time NOAA National Weather Service data. Returns water temperature, wind, barometric pressure, tide state, AQI, UV index, species-specific intelligence for 12 freshwater and saltwater species, and an optimal fishing window. Also provides a 7-day forecast and multi-spot comparison. Designed for fishing guides, outdoor apps, and AI agents that need a single-call conditions summary.\n"
  },
  "servers": [
    {
      "url": "https://fishpulse.waltsoft.net/v1",
      "description": "FishPulse production API"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/conditions": {
      "get": {
        "operationId": "getFishingConditions",
        "summary": "Real-time fishing conditions score (0-100) with species intel",
        "description": "Returns a fishing score (0-100), verdict, current conditions (water temp, air temp, wind, barometric pressure, tide state, AQI, UV index), species-specific activity ratings for up to 4 species, and an optimal fishing window. Weather data is live from NOAA NWS. Billed at $0.05 per successful call.\n",
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "35.22"
            },
            "description": "Latitude in decimal degrees (-90 to 90). Example: 35.22"
          },
          {
            "name": "lon",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "-80.84"
            },
            "description": "Longitude in decimal degrees (-180 to 180). Example: -80.84"
          },
          {
            "name": "activity",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fishing"
            },
            "description": "Activity type (default fishing). Examples: fishing, kayaking, surfing"
          }
        ],
        "responses": {
          "200": {
            "description": "Fishing conditions score and species intel",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "score",
                    "verdict",
                    "explanation",
                    "conditions",
                    "species_intel",
                    "optimal_window",
                    "location",
                    "activity",
                    "timestamp",
                    "data_sources"
                  ],
                  "properties": {
                    "score": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 100,
                      "description": "Fishing conditions score (0-100); 80+ excellent, 65-79 good, 45-64 fair, below 25 bad"
                    },
                    "verdict": {
                      "type": "string",
                      "description": "Human-readable verdict (e.g. \"Good \u2014 go fishing\")"
                    },
                    "explanation": {
                      "type": "string",
                      "description": "Brief explanation of the key factors driving the score"
                    },
                    "conditions": {
                      "type": "object",
                      "required": [
                        "water_temp_f",
                        "air_temp_f",
                        "wind_mph",
                        "wind_dir",
                        "barometric_hpa",
                        "pressure_trend",
                        "tide_state",
                        "aqi",
                        "uv_index"
                      ],
                      "properties": {
                        "water_temp_f": {
                          "type": "number",
                          "description": "Water temperature in Fahrenheit"
                        },
                        "air_temp_f": {
                          "type": "number",
                          "description": "Air temperature in Fahrenheit"
                        },
                        "wind_mph": {
                          "type": "number",
                          "description": "Wind speed in miles per hour"
                        },
                        "wind_dir": {
                          "type": "string",
                          "description": "Wind direction (e.g. SW, N, NE)"
                        },
                        "barometric_hpa": {
                          "type": "number",
                          "description": "Barometric pressure in hectopascals"
                        },
                        "pressure_trend": {
                          "type": "string",
                          "description": "Pressure trend (falling, stable, rising)"
                        },
                        "tide_state": {
                          "type": "string",
                          "description": "Tide state (incoming, high, outgoing, low)"
                        },
                        "aqi": {
                          "type": "integer",
                          "description": "Air Quality Index"
                        },
                        "uv_index": {
                          "type": "integer",
                          "description": "UV index (0-11)"
                        }
                      }
                    },
                    "species_intel": {
                      "type": "object",
                      "description": "Map of species key to activity rating and reason. Up to 4 species active at current water temperature. Keys: largemouth_bass, smallmouth_bass, trout, walleye, catfish, bluegill, crappie, pike, musky, striped_bass, redfish, snook\n",
                      "additionalProperties": {
                        "type": "object",
                        "required": [
                          "rating",
                          "reason"
                        ],
                        "properties": {
                          "rating": {
                            "type": "string",
                            "description": "Activity rating (excellent, good, fair)"
                          },
                          "reason": {
                            "type": "string",
                            "description": "Reason for the rating"
                          }
                        }
                      }
                    },
                    "optimal_window": {
                      "type": "string",
                      "description": "Optimal fishing window (e.g. \"Next 3 hours\", \"Evening bite (6-8pm)\")"
                    },
                    "location": {
                      "type": "object",
                      "required": [
                        "lat",
                        "lon"
                      ],
                      "properties": {
                        "lat": {
                          "type": "number"
                        },
                        "lon": {
                          "type": "number"
                        }
                      }
                    },
                    "activity": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "data_sources": {
                      "type": "object",
                      "required": [
                        "weather",
                        "water_temp",
                        "tide",
                        "pressure"
                      ],
                      "properties": {
                        "weather": {
                          "type": "string"
                        },
                        "water_temp": {
                          "type": "string"
                        },
                        "tide": {
                          "type": "string"
                        },
                        "pressure": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid lat/lon parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or inactive API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "402": {
            "description": "No API key sent -- x402 pay-per-call challenge"
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Weather service (NOAA NWS) unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/forecast": {
      "get": {
        "operationId": "getFishingForecast",
        "summary": "7-day fishing forecast with daily scores and best windows",
        "description": "Returns a multi-day fishing forecast with daily scores, verdicts, and best fishing windows. Also returns the best day in the forecast period. Up to 14 days. Billed at $0.05 per call.\n",
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "35.22"
            },
            "description": "Latitude in decimal degrees (-90 to 90)"
          },
          {
            "name": "lon",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "-80.84"
            },
            "description": "Longitude in decimal degrees (-180 to 180)"
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "7"
            },
            "description": "Forecast days (1-14, default 7)"
          },
          {
            "name": "activity",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fishing"
            },
            "description": "Activity type (default fishing)"
          }
        ],
        "responses": {
          "200": {
            "description": "Multi-day fishing forecast",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "location",
                    "activity",
                    "days",
                    "best_day",
                    "forecast",
                    "timestamp"
                  ],
                  "properties": {
                    "location": {
                      "type": "object",
                      "required": [
                        "lat",
                        "lon"
                      ],
                      "properties": {
                        "lat": {
                          "type": "number"
                        },
                        "lon": {
                          "type": "number"
                        }
                      }
                    },
                    "activity": {
                      "type": "string"
                    },
                    "days": {
                      "type": "integer"
                    },
                    "best_day": {
                      "type": "object",
                      "required": [
                        "date",
                        "score",
                        "verdict"
                      ],
                      "properties": {
                        "date": {
                          "type": "string",
                          "description": "ISO date (YYYY-MM-DD)"
                        },
                        "score": {
                          "type": "integer"
                        },
                        "verdict": {
                          "type": "string"
                        }
                      }
                    },
                    "forecast": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "date",
                          "day_of_week",
                          "score",
                          "verdict",
                          "conditions",
                          "best_window"
                        ],
                        "properties": {
                          "date": {
                            "type": "string",
                            "description": "ISO date (YYYY-MM-DD)"
                          },
                          "day_of_week": {
                            "type": "string"
                          },
                          "score": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 100
                          },
                          "verdict": {
                            "type": "string"
                          },
                          "conditions": {
                            "type": "object",
                            "required": [
                              "water_temp_f",
                              "air_temp_f",
                              "wind_mph",
                              "barometric_hpa",
                              "pressure_trend"
                            ],
                            "properties": {
                              "water_temp_f": {
                                "type": "number"
                              },
                              "air_temp_f": {
                                "type": "number"
                              },
                              "wind_mph": {
                                "type": "number"
                              },
                              "barometric_hpa": {
                                "type": "number"
                              },
                              "pressure_trend": {
                                "type": "string"
                              }
                            }
                          },
                          "best_window": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or inactive API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "402": {
            "description": "No API key sent -- x402 pay-per-call challenge"
          }
        }
      }
    },
    "/compare": {
      "get": {
        "operationId": "compareFishingSpots",
        "summary": "Compare fishing conditions across up to 5 locations",
        "description": "Compares real-time fishing conditions at up to 5 GPS locations and ranks them by score. Returns the recommended spot and per-spot conditions. Billed at $0.05 per call.\n",
        "parameters": [
          {
            "name": "spots",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "35.22,-80.84;34.05,-118.24"
            },
            "description": "Semicolon-separated lat,lon pairs (up to 5). Example: 35.22,-80.84;34.05,-118.24"
          },
          {
            "name": "activity",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fishing"
            },
            "description": "Activity type (default fishing)"
          }
        ],
        "responses": {
          "200": {
            "description": "Spot comparison ranked by fishing score",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "recommendation",
                    "spots",
                    "activity",
                    "timestamp"
                  ],
                  "properties": {
                    "recommendation": {
                      "type": "object",
                      "required": [
                        "location",
                        "score",
                        "verdict",
                        "water_temp_f",
                        "wind_mph"
                      ],
                      "properties": {
                        "location": {
                          "type": "object",
                          "required": [
                            "lat",
                            "lon"
                          ],
                          "properties": {
                            "lat": {
                              "type": "number"
                            },
                            "lon": {
                              "type": "number"
                            }
                          }
                        },
                        "score": {
                          "type": "integer"
                        },
                        "verdict": {
                          "type": "string"
                        },
                        "water_temp_f": {
                          "type": "number"
                        },
                        "wind_mph": {
                          "type": "number"
                        }
                      }
                    },
                    "spots": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "location",
                          "score",
                          "verdict",
                          "water_temp_f",
                          "wind_mph"
                        ],
                        "properties": {
                          "location": {
                            "type": "object",
                            "properties": {
                              "lat": {
                                "type": "number"
                              },
                              "lon": {
                                "type": "number"
                              }
                            }
                          },
                          "score": {
                            "type": "integer"
                          },
                          "verdict": {
                            "type": "string"
                          },
                          "water_temp_f": {
                            "type": "number"
                          },
                          "wind_mph": {
                            "type": "number"
                          }
                        }
                      }
                    },
                    "activity": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid spots parameter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or inactive API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "402": {
            "description": "No API key sent -- x402 pay-per-call challenge"
          }
        }
      }
    },
    "/species/{name}": {
      "get": {
        "operationId": "getSpeciesInfo",
        "summary": "Species temperature and pressure preferences (free -- no auth required)",
        "description": "Returns a species profile with temperature range, ideal temperature, pressure preference, best fishing time, depth range, and notes. Use \"list\" as the name to get all available species. This endpoint is free and requires no API key.\n",
        "security": [],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "largemouth_bass"
            },
            "description": "Species key (e.g. largemouth_bass, trout, walleye, catfish, bluegill, crappie, pike, musky, striped_bass, redfish, snook, smallmouth_bass) or \"list\" to get all species\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Species profile or list of available species",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "description": "Species profile",
                      "required": [
                        "name",
                        "temp_range_f",
                        "ideal_temp_f",
                        "pressure_preference",
                        "best_time",
                        "depth_ft",
                        "notes"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "temp_range_f": {
                          "type": "array",
                          "items": {
                            "type": "number"
                          },
                          "description": "[min, max] temperature range in Fahrenheit"
                        },
                        "ideal_temp_f": {
                          "type": "number"
                        },
                        "pressure_preference": {
                          "type": "string"
                        },
                        "best_time": {
                          "type": "string"
                        },
                        "depth_ft": {
                          "type": "string"
                        },
                        "notes": {
                          "type": "string"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "description": "Species list (when name=list)",
                      "required": [
                        "species",
                        "count"
                      ],
                      "properties": {
                        "species": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "count": {
                          "type": "integer"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Species not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "AuthError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}