{
  "openapi": "3.1.0",
  "info": {
    "title": "Flow Diesel Prices API",
    "version": "1.0.0",
    "description": "Posted retail diesel prices at US truck stops from ValveRide Flow. Authenticate with a developer API key from https://app.valverideflow.com/developers sent as Authorization: Bearer vrf_dev_YOUR_KEY. New accounts start with a one-time $20 signup credit; after that, choose a monthly plan in the developer dashboard. Use of the API is subject to the API Terms at https://valverideflow.com/api-terms.",
    "contact": {
      "name": "ValveRide",
      "url": "https://valverideflow.com/contact"
    }
  },
  "servers": [
    {
      "url": "https://app.valverideflow.com/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/prices/station/{id}": {
      "get": {
        "operationId": "getStationPrice",
        "summary": "Diesel price at one truck stop",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^pf_[0-9a-f]{16}$"
            }
          },
          {
            "name": "include_estimated",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "Include estimated prices for stations without a recent posted price."
          }
        ],
        "responses": {
          "200": {
            "description": "The station's price, or data null when it has no price to offer.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/StationPrice"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown station id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account's monthly plan is cancelled or unpaid (code subscription_inactive).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The endpoint is not on this key's plan (forbidden_endpoint), or the key reached its monthly distinct station cap (station_cap_reached).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests on this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/prices/near": {
      "get": {
        "operationId": "getPricesNear",
        "summary": "Diesel prices at truck stops near a point, nearest first",
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            }
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          {
            "name": "radius",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0,
              "maximum": 50,
              "default": 10
            },
            "description": "Search radius in miles."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "include_estimated",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "Include estimated prices for stations without a recent posted price."
          }
        ],
        "responses": {
          "200": {
            "description": "Stations with a price to offer.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/StationPrice"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account's monthly plan is cancelled or unpaid (code subscription_inactive).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The endpoint is not on this key's plan (forbidden_endpoint), or the key reached its monthly distinct station cap (station_cap_reached).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests on this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Developer API key (vrf_dev_...)."
      }
    },
    "schemas": {
      "StationPrice": {
        "type": "object",
        "required": [
          "station_id",
          "source",
          "brand",
          "name",
          "city",
          "state",
          "lat",
          "lng",
          "price",
          "confidence",
          "estimated",
          "observed_at"
        ],
        "properties": {
          "station_id": {
            "type": "string",
            "pattern": "^pf_[0-9a-f]{16}$",
            "description": "Public station id."
          },
          "source": {
            "type": "string",
            "enum": [
              "ValveRide Flow"
            ]
          },
          "brand": {
            "type": [
              "string",
              "null"
            ],
            "description": "Truck stop brand display name."
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ],
            "description": "Two-letter state or province code."
          },
          "lat": {
            "type": [
              "number",
              "null"
            ]
          },
          "lng": {
            "type": [
              "number",
              "null"
            ]
          },
          "price": {
            "type": "number",
            "description": "Posted retail diesel price in USD per gallon."
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "estimated": {
            "type": "boolean",
            "description": "True when the price is an estimate rather than a recent posted price."
          },
          "observed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          }
        }
      }
    }
  }
}
