DiscGolfAPI Courses API

Course list and course detail endpoints.

Documentation

Specifications

Schemas & Data

Other Resources

OpenAPI Specification

discgolfapi-courses-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: DiscGolf Countries Courses API
  version: 1.0.0
  description: DiscGolfAPI is a read-only API for structured disc golf course data. It provides stable course records, location fields, country and region indexes, update metadata, confidence signals and attribution information for developer projects, maps, directories, websites and AI systems.
  termsOfService: https://discgolfapi.com/terms/
  contact:
    name: DiscGolfAPI
    url: https://discgolfapi.com/contact/
  license:
    name: Free to use with attribution
    url: https://discgolfapi.com/licence/
servers:
- url: https://io.discgolfapi.com/v1
  description: Production API
tags:
- name: Courses
  description: Course list and course detail endpoints.
paths:
  /courses:
    get:
      tags:
      - Courses
      summary: List Courses
      description: Returns public disc golf course records. Use country and region filters where available, and limit and offset for pagination.
      operationId: listCourses
      parameters:
      - $ref: '#/components/parameters/Country'
      - $ref: '#/components/parameters/Region'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Offset'
      responses:
        '200':
          description: A course list response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseListResponse'
              examples:
                gbList:
                  summary: One Great Britain course
                  value:
                    schema_version: 1.0.0
                    generated_at: '2026-05-03T18:02:34.285060Z'
                    attribution: Course data supplied by DiscGolfAPI.
                    attribution_required: true
                    license: Free to use with attribution.
                    license_url: https://discgolfapi.com/licence/
                    terms_url: https://discgolfapi.com/terms/
                    no_warranty: Data is provided as-is. Accuracy, completeness and availability are not guaranteed.
                    meta:
                      publish_version: 20260503T180234Z
                      release_scope: all
                    count: 1
                    total: 30
                    offset: 0
                    courses:
                    - id: crs_ackers_adventure
                      slug: ackers-adventure
                      name: Ackers Adventure
                      lat: 52.4579339107501
                      lon: -1.85255245845531
                      country_code: GB
                      region_code: ENG
                      locality: null
                      website: https://ackers-adventure.co.uk/
                      operator_name: null
                      holes: null
                      existence_status: existing
                      operational_status: open
                      access_model: unknown
                      condition_status: unknown
                      listing_status: listed
                      confidence_score: 0.65
                      verification_strength: medium
                      last_verified_at: '2026-04-27T22:40:53.197339Z'
                      updated_at: '2026-04-29T20:35:03.752326Z'
                      primary_layout:
                        id: c30f319b-b111-4b94-afd1-77585659f6f2
                        slug: main-layout
                        name: Main Layout
                        holes: null
                        par_total: null
                        length_meters: null
                        confidence_score: 0.65
                        verification_strength: medium
                        last_verified_at: '2026-04-27T22:40:53.197339Z'
                      attributes: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/ServerError'
  /courses/{id}:
    get:
      tags:
      - Courses
      summary: Get a Course by ID
      description: Returns a single course by stable public course ID. The response uses the same envelope and courses array shape as the list endpoint.
      operationId: getCourse
      parameters:
      - $ref: '#/components/parameters/CourseId'
      responses:
        '200':
          description: A single course response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  parameters:
    Country:
      name: country
      in: query
      required: false
      description: Country code filter.
      schema:
        type: string
        minLength: 2
        maxLength: 2
        examples:
        - GB
    Offset:
      name: offset
      in: query
      required: false
      description: Number of matching records to skip before returning the current page.
      schema:
        type: integer
        minimum: 0
        default: 0
        examples:
        - 0
    Region:
      name: region
      in: query
      required: false
      description: Region, state or subdivision code filter where supported.
      schema:
        type: string
        examples:
        - ENG
    CourseId:
      name: id
      in: path
      required: true
      description: Stable public course ID.
      schema:
        type: string
        pattern: ^crs_[a-z0-9_]+$
        examples:
        - crs_ackers_adventure
    Limit:
      name: limit
      in: query
      required: false
      description: Maximum number of records to return. Must be a positive integer.
      schema:
        type: integer
        minimum: 1
        examples:
        - 5
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
      required:
      - error
      additionalProperties: true
    PaginationMeta:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        total:
          type: integer
          minimum: 0
        offset:
          type: integer
          minimum: 0
      required:
      - count
    CommonEnvelope:
      type: object
      properties:
        schema_version:
          type: string
        generated_at:
          type: string
          format: date-time
        attribution:
          type: string
        attribution_required:
          type: boolean
        license:
          type: string
        license_url:
          type: string
          format: uri
        terms_url:
          type: string
          format: uri
        no_warranty:
          type: string
        meta:
          $ref: '#/components/schemas/ResponseMeta'
      required:
      - schema_version
      - generated_at
      - attribution
      - attribution_required
      - license
      - license_url
      - terms_url
      - no_warranty
    PrimaryLayout:
      type: object
      properties:
        id:
          type: string
        slug:
          type: string
        name:
          type: string
        holes:
          type:
          - integer
          - 'null'
          minimum: 1
        par_total:
          type:
          - integer
          - 'null'
          minimum: 1
        length_meters:
          type:
          - number
          - 'null'
          minimum: 0
        confidence_score:
          type: number
          minimum: 0
          maximum: 1
        verification_strength:
          type: string
        last_verified_at:
          type:
          - string
          - 'null'
          format: date-time
      required:
      - id
      - slug
      - name
      - holes
      - par_total
      - length_meters
      - confidence_score
      - verification_strength
      - last_verified_at
    CourseListResponse:
      allOf:
      - $ref: '#/components/schemas/CommonEnvelope'
      - $ref: '#/components/schemas/PaginationMeta'
      - type: object
        properties:
          courses:
            type: array
            items:
              $ref: '#/components/schemas/Course'
        required:
        - courses
    CourseResponse:
      allOf:
      - $ref: '#/components/schemas/CommonEnvelope'
      - $ref: '#/components/schemas/PaginationMeta'
      - type: object
        properties:
          courses:
            type: array
            minItems: 1
            maxItems: 1
            items:
              $ref: '#/components/schemas/Course'
        required:
        - courses
    ResponseMeta:
      type: object
      properties:
        publish_version:
          type: string
        release_scope:
          type: string
      additionalProperties: true
    Course:
      type: object
      properties:
        id:
          type: string
        slug:
          type: string
        name:
          type: string
        lat:
          type:
          - number
          - 'null'
        lon:
          type:
          - number
          - 'null'
        country_code:
          type: string
        region_code:
          type:
          - string
          - 'null'
        locality:
          type:
          - string
          - 'null'
        website:
          type:
          - string
          - 'null'
          format: uri
        operator_name:
          type:
          - string
          - 'null'
        holes:
          type:
          - integer
          - 'null'
          minimum: 1
          description: Known hole count. Null means unknown, not zero.
        existence_status:
          type: string
        operational_status:
          type: string
        access_model:
          type: string
        condition_status:
          type: string
        listing_status:
          type: string
        confidence_score:
          type: number
          minimum: 0
          maximum: 1
        verification_strength:
          type: string
        last_verified_at:
          type:
          - string
          - 'null'
          format: date-time
        updated_at:
          type: string
          format: date-time
        primary_layout:
          anyOf:
          - $ref: '#/components/schemas/PrimaryLayout'
          - type: 'null'
        attributes:
          type:
          - object
          - 'null'
          additionalProperties: true
      required:
      - id
      - slug
      - name
      - lat
      - lon
      - country_code
      - region_code
      - locality
      - website
      - operator_name
      - holes
      - existence_status
      - operational_status
      - access_model
      - condition_status
      - listing_status
      - confidence_score
      - verification_strength
      - last_verified_at
      - updated_at
      - primary_layout
      - attributes
  responses:
    NotFound:
      description: Resource not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            courseNotFound:
              value:
                error: Course not found
    BadRequest:
      description: Invalid request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ServerError:
      description: Temporary server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    TooManyRequests:
      description: Too many requests.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
externalDocs:
  description: DiscGolfAPI documentation
  url: https://discgolfapi.com/docs/