> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thebuoy.app/llms.txt
> Use this file to discover all available pages before exploring further.

# List all buoys

> Get a paginated list of buoys with optional filtering by geographic bounds, source, or active status.

Returns buoys in a standardized V2 format with pagination metadata.




## OpenAPI

````yaml /api-reference/openapi.json get /buoys
openapi: 3.0.3
info:
  title: The Buoy API
  version: 2.0.0
  description: >-
    **The Buoy API** — programmatic access to ocean wave buoys on The Surf Kit
    platform.


    All operations are **read-only** (`GET`). Data includes live and historical
    readings, geographic filters, chart time series, and **`GET /conditions`**
    (combined forecast, buoy reading, and tide for a point).


    ## Authentication


    Pass your API key in the `Authorization` header:


    ```

    Authorization: Bearer YOUR_API_KEY

    ```


    `GET /buoys/search` and `GET /buoys/nearest` are public (no key required).


    ## Rate limiting


    Responses include `X-RateLimit-*` headers. Exceeding your hourly quota
    returns `429 Too Many Requests`.
  contact:
    name: API Support
    email: thomas@thebuoy.app
  license:
    name: Proprietary
servers:
  - url: https://api.thebuoy.app/v2
    description: Production server (V2)
  - url: http://localhost:3000/api/v2
    description: Development server (V2)
security:
  - ApiKeyAuth: []
tags:
  - name: Buoys
    description: Real-time ocean buoy data
  - name: Satellite Passes
    description: >-
      Satellite altimeter passes over virtual buoys, and the missions behind
      them
  - name: Conditions
    description: All-in-one conditions endpoint
paths:
  /buoys:
    get:
      tags:
        - Buoys
      summary: List all buoys
      description: >
        Get a paginated list of buoys with optional filtering by geographic
        bounds, source, or active status.


        Returns buoys in a standardized V2 format with pagination metadata.
      operationId: listBuoys
      parameters:
        - name: bounds
          in: query
          description: >-
            Geographic bounding box as JSON string
            `{"north":44,"south":43,"east":-1,"west":-2}`
          schema:
            type: string
          example: '{"north":44,"south":43,"east":-1,"west":-2}'
        - name: near
          in: query
          description: >-
            Coordinates and radius in format `lat,lng` (e.g., "43.5,-1.5"). Use
            with `radius` parameter.
          schema:
            type: string
          example: 43.5,-1.5
        - name: radius
          in: query
          description: >-
            Search radius in kilometers (used with `near` parameter, default:
            100)
          schema:
            type: integer
            default: 100
        - name: source
          in: query
          description: Filter by source (e.g., "Candhis", "Meteo France", "Sofar Ocean")
          schema:
            type: string
        - name: country
          in: query
          description: >-
            Filter by ISO 3166-1 alpha-2 country code (e.g., "FR", "ES", "PT").
            When set, up to 500 buoys are returned per page.
          schema:
            type: string
            pattern: ^[A-Z]{2}$
          example: FR
        - name: active_only
          in: query
          description: 'Only return buoys with recent readings (default: true)'
          schema:
            type: boolean
            default: true
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: per_page
          in: query
          schema:
            type: integer
            default: 50
            maximum: 500
      responses:
        '200':
          description: Successful response
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      buoys:
                        type: array
                        items:
                          $ref: '#/components/schemas/Buoy'
                      count:
                        type: integer
                        description: Total number of buoys matching filters
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
              example:
                status: success
                data:
                  buoys:
                    - id: 10
                      name: Anglet
                      lat: 43.4832
                      lng: -1.5586
                      source: Candhis
                      source_identifier: '64002'
                      last_reading_time: '2025-11-01T10:00:00Z'
                      readings_count: 125430
                      last_reading:
                        uuid: abc-123-def
                        significient_height: 1.5
                        maximum_height: 2
                        period: 8.5
                        time: '2025-11-01T10:00:00Z'
                        water_temperature: 18.5
                        direction: 270
                        unit: m
                  count: 1
                meta:
                  page: 1
                  per_page: 50
                  total_pages: 1
                  timestamp: '2025-11-01T10:00:00Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
      security:
        - ApiKeyAuth: []
components:
  headers:
    XRateLimitLimit:
      schema:
        type: integer
        description: Maximum requests allowed per hour
        example: 1000
      description: Maximum requests allowed per hour
    XRateLimitRemaining:
      schema:
        type: integer
        description: Requests remaining in current hour
        example: 987
      description: Requests remaining in current hour
    XRateLimitReset:
      schema:
        type: integer
        description: Unix timestamp when rate limit resets
        example: 1735326000
      description: Unix timestamp when rate limit resets
  schemas:
    Buoy:
      type: object
      description: Basic buoy information
      properties:
        id:
          type: integer
        name:
          type: string
        lat:
          type: number
          format: float
        lng:
          type: number
          format: float
        source:
          type: string
          description: Data source (e.g., "Candhis", "Meteo France", "Sofar Ocean")
        source_identifier:
          type: string
          description: Source-specific identifier
        last_reading_time:
          type: string
          format: date-time
          description: Timestamp of most recent reading
        readings_count:
          type: integer
          description: Total number of readings for this buoy
        last_reading:
          $ref: '#/components/schemas/BuoyReading'
    PaginationMeta:
      type: object
      description: Pagination metadata included in list responses
      properties:
        page:
          type: integer
          description: Current page number
          example: 1
        per_page:
          type: integer
          description: Number of items per page
          example: 50
        total_pages:
          type: integer
          description: Total number of pages
          example: 5
        timestamp:
          type: string
          format: date-time
          description: Response timestamp in ISO 8601 format
    BuoyReading:
      type: object
      description: Individual buoy reading
      properties:
        id:
          type: integer
        uuid:
          type: string
          description: Unique identifier for the reading
        significient_height:
          type: number
          format: float
          description: Significant wave height in meters
        maximum_height:
          type: number
          format: float
          description: Maximum wave height in meters
        period:
          type: number
          format: float
          description: Wave period in seconds
        time:
          type: string
          format: date-time
          description: Reading timestamp
        water_temperature:
          type: number
          format: float
          description: Water temperature in Celsius
        direction:
          type: integer
          description: Wave direction in degrees (0-360)
        direction_compass:
          type: string
          description: Compass direction (e.g., "SW", "NW")
        unit:
          type: string
          description: Unit abbreviation (e.g., "m")
        energy_per_wave:
          type: number
          format: float
          description: Energy per wave in kilojoules
    ErrorResponse:
      type: object
      description: Standardized error response format for V2 API
      properties:
        error:
          type: string
          description: >-
            Error code (e.g., "unauthorized", "bad_request",
            "resource_not_found")
          example: unauthorized
        message:
          type: string
          description: Human-readable error message
          example: Invalid API key
        details:
          type: object
          description: Additional error details (optional, varies by error type)
  responses:
    BadRequest:
      description: Bad request (400 Bad Request)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: bad_request
            message: Search term must be at least 2 characters
            timestamp: '2025-12-27T14:30:00Z'
            request_id: 550e8400-e29b-41d4-a716-446655440000
    Unauthorized:
      description: Invalid or missing API key (401 Unauthorized)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: unauthorized
            message: Invalid API key
            timestamp: '2025-12-27T14:30:00Z'
            request_id: 550e8400-e29b-41d4-a716-446655440000
    RateLimitExceeded:
      description: Rate limit exceeded (429 Too Many Requests)
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
            description: Maximum requests allowed per hour
            example: 1000
        X-RateLimit-Remaining:
          schema:
            type: integer
            description: Requests remaining in current hour
            example: 0
        X-RateLimit-Reset:
          schema:
            type: integer
            description: Unix timestamp when rate limit resets (top of next hour)
            example: 1735326000
        Retry-After:
          schema:
            type: integer
            description: Seconds to wait before retrying
            example: 3600
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: rate_limit_exceeded
            message: You have exceeded 1000 requests per hour
            timestamp: '2025-12-27T14:30:00Z'
            request_id: 550e8400-e29b-41d4-a716-446655440000
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >
        API key authentication. Pass your API key as a Bearer token in the
        Authorization header.


        Format: `Authorization: Bearer YOUR_API_KEY`


        Alternative: Pass as query parameter `?api_key=YOUR_API_KEY`


        **Security:** API keys are stored as BCrypt hashes (never plain text).
        Only the hash is stored in the database.

````