openapi: 3.0.0

info:
  title: swipos-API
  description: |

    ![](https://shop.swipos.ch/Images/BundesverwaltungLogo.jpg)
    ***
    The swipos-API provides an application interface to the Swiss Positioning Service swipos.
    This is the main documentation which includes all the swipos-API documentation for developers.

    **The swipos-API is part of the [swipos-GIS/GEO](https://www.swisstopo.admin.ch/de/swipos-gisgeo-fuer-rtk-und-postprocessing-anwendungen) product. To access the swipos-API, you need a valid swipos-GIS/GEO license, which can be ordered via the [Pricing and Order](https://www.swisstopo.admin.ch/de/swipos-dienste-preise-und-bestellung) page.**

    The swipos-API currently consists of the RINEX Download, which offers an interface to the AGNES station information and their RINEX data (CORS).

    ## Data availability

    RINEX data is available for full hours, or it can be requested for a desired duration. A full hour is available roughly 5 minutes after the hour is complete. You can request data for the last 356 days.

    # swipos-API conventions

    When using the swipos-API, the following conventions apply:

    ## Time
    Dates, times and durations are expressed in a custom format that is based on **ISO 8601**.

    GPS time is usually given in seconds, and is related to the international atomic time (TAI). This differs from the Universal Time Coordinated (UTC), which is kept synchronized to the earth's rotation by leap seconds. The relation can be expressed as *GPSTime = UTC + 18s*

    To simplify the use of the swipos-API, we kept the formats proposed in ISO 8601, and added **G** as a timezone indicator instead of the **Z** used for UTC time. Times that do not end with **G** are treated as having invalid format.

    The swipos-API accepts only durations of up to 6 hours, so all durations must start with PT (period, time), followed by the duration in hours and/or minutes.

    If requesting an hour file, it is enough to fill the hour; it is not necessary to give minutes or seconds.

    **Examples:**

    - basic format: `yyyyMMddThhmmG / 20200821T1313G` OR `yyyMMddThhG / 20210217T05G`
    - extended format: `yyyy-MM-ddThh:mmG / 2020-08-21T13:13G`
    - duration (in hours, minutes): `PTnHmmM / PT3H30M`

    As of now, times without the timezone G will not be considered valid times.


    ### Epochs
    The RINEX data is recorded at the base station and will be sent every hour to the swipos servers. One hour file contains 3600 epochs if all recordings were successful. An hour file will be available around 20 minutes after the hour has ended.

    Please note, that the delivered RINEX files may not contain 100% of the epochs due to recording issues.

    ## Coordinate system
    Unless otherwise stated, the swipos-API uses latitude and longitude in decimal degrees in the **ETRS89** reference system.

    **Example:**
      `46.28310, 7.53854`

    **Note:** The coordinates in the base station information are to be used for representation only, they are not intended for geodetic calculations. The geocentric coordinates contained in the RINEX file as approximate position can be used as precise coordinates.

    ## RINEX 3.04
    The delivered RINEX format is 3.04 with 1 second sampling rate as recorded at the base stations (Trimble NetR9 or Leica GR50).
    To manipulate the RINEX, the RINEX GNSS Data Conversion and Manipulation Toolbox "gfzrnx" is used:
    Nischan,  Thomas  (2016):  GFZRNX  -  RINEX  GNSS  Data  Conversion  and  Manipulation  Toolbox.
    [GFZ  DataServices](http://dx.doi.org/10.5880/GFZ.1.1.2016.002)

    The RINEX files are compressed with [hatanaka](https://terras.gsi.go.jp/ja/crx2rnx.html). The download includes both the observation and navigation files.


    ## Station code
    The base station is always identified by its 4 character station code, which is case sensitive and must use capital letters, as returned by the /list endpoint.

    **Example:**
      `ZIM2`

    ## Authentication

    The swipos-API uses basic authentication for the calls to request-hour and request-data. Any swipos login with a valid swipos-GIS/GEO License can be used with the exception of Pay-per-Use licenses, which are not supported.

    ## swipos-API specification
    The api specification was defined as openapi version 3.0.0 [openapi spec](https://github.com/OAI/OpenAPI-Specification/).  
    Here you can find the current developement api specification [api-docs.yml](https://swipos-dev-apidoc.s3.eu-central-1.amazonaws.com/api-docs.yml).  
    Here you can find the current productive api specification [api-docs.yml](https://swipos-apidoc.s3.eu-central-1.amazonaws.com/api-docs.yml).  
    To generate clients use [openapi-generator](https://openapi-generator.tech/).

    
    ### Versioning
    Versions are named after plants. Version are alphabetically sorted, where letters later in the alphabet corresnpond with a version published later in time. For minor releases, the second or third letter of the name is significant.
    
    **Examples:**
    
    - `acacia` - 1st release
    - `aconite` - 1st minor release
    - `begonia` - 2nd release


  contact:
    name: swipos-API Support
    url: https://swisstopo.ch/swipos
    email: swipos@swisstopo.ch

  version: "acacia"

  license:
    name: Apache 2.0

security:
  - basicAuth: []

servers:
  - url: "https://api.swipos.ch/acacia"

tags:
  - name: "RINEX"
    description: swipos-API endpoints that provide RINEX services.

paths:
  /rinex/station/list:
    get:
      tags:
        - "RINEX"
      summary: Returns a list of all AGNES stations.
      description: The request returns an array of BaseStation objects, which for each base station give the station code, postion and if the station is still operational.
      operationId: list
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BaseStation'
  /rinex/station/nearest:
    get:
      tags:
        - "RINEX"
      summary: The base station object of the nearest active AGNES station.
      description: Specify a point and get the closest active AGNES station back. If no time arguments are supplied, returns nearest station without consideration if the station is operational at the moment or not. In case of 'time_from' argument, returns nearest station that was active at that moment. In case of 'time_from' and 'time_to' or 'period' arguments, returns a station with activity in described time frame.
      operationId: nearest
      parameters:
        - in: query
          name: latitude
          schema:
            type: number
            format: double
            example: 46.38851
          required: true
          description: Latitude of your position. *Example 46.38851*
        - in: query
          name: longitude
          schema:
            type: number
            format: double
            example: 7.05977
          required: true
          description: Longitude of your position. *Example 7.05977*
        - in: query
          name: time_from
          schema:
            type: string
          required: false
          description: Filter for stations that were operational starting at this time point (e.g. yyyy-MM-ddThh:00G or yyyyMMddThh00G)
        - in: query
          name: time_to
          schema:
            type: string
          required: false
          description: Filter for stations that were operational until this time point (e.g. yyyy-MM-ddThh:00G or yyyyMMddThh00G)
      responses:
        '200':
          description: A base station object and its distance to your position
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NearestStation'
        '400':
          description: >-
            Bad Request. Possible reasons are:  
            
            
            * 102 - No base station for given criteria
            
            * 103 - Invalid latitude or longitude format
            
            * 104 - No parameters given
            
            * 108 - Mandatory parameter 'latitude' is missing. OR Mandatory parameter 'longitude' is missing  

          content:
              application/json:
                schema:
                  $ref: '#/components/schemas/Error'
                  
  /rinex/station/request-hour:
    get:
      tags:
        - "RINEX"
      summary: Request an existing hour RINEX file for a station code.
      description: Request the hour file from a station with the station_code (eg. SAA2) and hour (eg. "2020-08-17T13:00G" or "2020081713G"). The endpoint will return the coresponding rinex hour file. *Note* The hour file is written in GPS time, so has 18s offset to UTC times. Use this if you need a full hour.
      operationId: request-hour
      parameters:
        - in: query
          name: station_code
          schema:
            type: string
          required: true
          description: Station code
        - in: query
          name: time
          schema:
            type: string
          required: true
          description: Requesting hour starting at (e.g. yyyy-MM-ddThh:00G or yyyyMMddThh00G)
      responses:
        '200':
          description: A RINEX file.
          content:
            octet_stream/zip:
              schema:
                $ref: '#/components/schemas/HourlyRinexResponse'
        '400':
          description: >-
            Bad Request. Possible reasons are:


            * 104 - There are no params at all

            * 105 - Can not get data for time in future (or this recent)

            * 106 - No base station data for given time and station code

            * 107 - Mandatory field 'station_code' must be 4 capital letters and/or mandatory field 'time' is not given as yyyy-mm-ddThh:mmG or yyyymmddhhmmG

            * 108 - Mandatory field 'station_code' and/or 'time' is missing

          content:
              application/json:
                schema:
                  $ref: '#/components/schemas/Error'
  /rinex/station/request-data:
    post:
      tags:
        - "RINEX"
      summary: Request up to 6 hours of rinex data from one AGNES station.
      description:
        Use this you need data from more than one RINEX hour files. For requesting, you need the AGNES station code as well as the starting date and time. You can either give a duration or an end time. The result will be submitted to the provided callback url. **Note** One request can handle a maximum of 6 hours at once. If you need one hour only, use 'request-hour' instead.
      operationId: request-data
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RequestData'  
      callbacks:
        Request completed:
           Callback:
            post:
              summary: A POST request with the request-data result.
              operationId: request_completed_callback
              requestBody:
                required: true
                content:
                  application/json: # Contents of the callback message
                    schema:
                       $ref: '#/components/schemas/CallbackAnswer'
              responses:   # Expected responses to the callback message
                      '200':
                        description: Your server returns this code if it consumes the request-data result.
      responses:
        '202':
          description: An object representing a scheduled request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledRequest'
        '400':
          description: >-
            Bad Request. Possible reasons are:
            

            * 101 - Could not create url on s3

            * 104 - There are no params at all

            * 105 - Can not get data for time in future (or this recent)

            * 106 - No base station data for given time and station code

            * 107 - Field 'time_from' or 'time_to' is not of proper format / Duration is not a valid ISO8601 value / Mandatory field 'station_code' is not of length 4

            * 108 - Mandatory field 'time_from', 'duration' or 'station_code' is missing

            * 109 - One of fields 'time_from','time_to' or 'duration' is not of proper format

            * 110 - Duration is less than allowed minimum

            * 111 - Duration is greater than allowed maximum

            * 113 - Can not get data for period in future (or this recent)

            * 114 - Time frame must be within a single day

            * 115 - Invalid callback url

            * 116 - Invalid email format

            * 117 - Could not queue a task

          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
  schemas:
    BaseStation:
      type: object
      required: ["station_code", "active_from", "latitude", "longitude"]
      properties:
          station_code:
            type: string
            description: Existing AGNES station code, must be capitalized
            example: FHBB
          active_from:
            type: string
            description: When the station was taken into operation
            example: 1998-08-25T00:00G
          active_to:
            type: string
            description: If a datetime, the station stopped operation on this date. If "now", the station is still operational.
            example: 2018-09-12T06:25G
          latitude:
            type: number
            format: double
            example: 47.5346
          longitude:
            type: number
            format: double
            example: 7.64189
    HourlyRinexResponse:
      type: object
      properties:
        rinex_response:
          type: string
          format: binary
          description: Ordered hourly rinex file
    NearestStation:
      type: object
      properties:
          base_station:
            $ref: "#/components/schemas/BaseStation"
          distance:
            type: number
            example: 12.64378
            description: Distance to the nearest station, in km.
    Error:
      type: object
      required:
        - message
        - error_code
      properties:
        message:
          type: string
          example: There are no params at all.
        error_code:
          type: integer
          example: 104
    RequestData:
          type: object
          required:
            - time_from
            - duration # only one of the fields ["to", "duration"] is compulsory, no?
            - station_code
          properties:
            station_code:
              type: string
              example: AIGE
              description: A valid 4-character base station code in capital letters.
            time_from:
              type: string
              example: 2020-08-17T13:00G
              description: An ISO 8601 timestamp that defines start of desired period.
            time_to:
              type: string
              example: 2020-08-17T13:23G
              description: An ISO 8601 timestamp that defines end of desired period.
            duration:
              type: string
              example: PT23M
              description: An ISO 8601 period that defines length of desired period. Minimum duration must be 5 minutes (PT5M)
            callback_url:
              type: string
              format: uri
              example: https://myserver.com/send/callback/here
              description: This url will be triggered with a POST request with CallbackAnswer in body.
            include_log:
              type: string
              example: yes
              description: If there is a value like ‘true’, ‘1’, ‘yes’, ‘y’, case insensitive, resulting archive will contain logs from merge process.
            observation_only:
              type: string
              example: yes
              description: If there is a value like ‘true’, ‘1’, ‘yes’, ‘y’, case insensitive, resulting archive will not contain NAV files. In case 'include_log' is false, the resulting file will be a single observation rinex file.
    ScheduledRequest:
      type: object
      required:
        - request_id
        - preassigned_url
        - requested_duration
        - with_callback
      properties:
        request_id:
          description: A unique merge request identifier.
          type: string
          example: db610686-4ce8-403e-8338-85437b326618
        station_code:
          type: string
          example: AIGE
          description: A unique 4-letter base station code.
        time_from:
          type: string
          example: 2020-08-17T13:00G
          description: An ISO 8601 timestamp that defines start of desired period.
        time_to:
          type: string
          example: 2020-08-17T13:23G
          description: An ISO 8601 timestamp that defines end of desired period.
        duration:
          type: string
          example: PT23M
        with_callback:
          type: boolean
          example: true
        with_email_notification:
          type: boolean
          example: true
        preassigned_url:
          type: string
          format: url
          example: 'https://rinexmergeresults.com/15810350001581036000.rnx'
    CallbackAnswer:
      type: object
      required:
        - request_id
        - merge_status
        - resource_url
        - station_code
      properties:
        request_id:
          type: string
          example: "81dd2e93-d98c-413a-b26d-f9790146c862"
        merge_status:
          type: boolean
          example: true
        resource_url:
          type: string
          format: url
          example: 'https://swipos-delivery.s3.amazonaws.com/AIGE_27T135900G_9E1782A1.ZIP'
        station_code:
          type: string
          example: "AIGE"
        error_code:
          type: number
          example: 128
        error_message:
          type: string
          example: "Missing files for this time range!"
