openapi: "3.0.0"
info:
  title: IndoorAtlas Positioning API
  description: Locate devices using Wi-Fi and access IndoorAtlas venue and floor plan metadata.
    Metadata is only available for mapped venues.
    Remember to add your API key as the `key` query string parameter to all requests to access this API, for example `https://positioning-api.indooratlas.com/v1/venues/VENUE_ID?key=MY_API_KEY`.
    Open API spec available [here](https://docs.indooratlas.com/positioning-api.yaml)
    The China endpoint (indooratlas-cn.com) returns coordinates in GCJ-02 instead of WGS84.
  version: "1.3.0"
servers:
  - url: https://positioning-api.indooratlas.com/v1
  - url: https://positioning-api.indooratlas-cn.com/v1
paths:
  /locate:
    post:
      summary: Locate
      description: Locate a device based on its radio environment
      externalDocs:
        description: For more info about iBeacons, see Apple documentation
        url: https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf
      requestBody:
        description: Radio environment observations. Include all access points from a Wi-Fi scan or iBeacons from a BLE scan.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LocateRequest"
      tags:
        - Locate
      responses:
        '200':
          description: Location estimate
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LocateResponse"
        '422':
          description: Request is missing required fields or contains invalid values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UnprocessableRequestError"
        '400':
          description: Unable to understand the request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        '429':
          $ref: "#/components/responses/TooManyRequests"
        default:
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /floor_plans/{floorPlanId}:
    get:
      summary: Floor plan
      description: Get floor plan details
      parameters:
        - in: path
          name: floorPlanId
          schema:
            type: string
            format: uuid
          required: true
          description: IndoorAtlas floor plan ID
      tags:
        - Floor plans
      responses:
        '200':
          description: Floor plan information
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FloorPlan"
        '404':
          description: No mapped floor plan found with given ID
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        '429':
          $ref: "#/components/responses/TooManyRequests"
        default:
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /venues/{venueId}:
    get:
      summary: Venue
      description: Get venue details
      parameters:
        - in: path
          name: venueId
          schema:
            type: string
            format: uuid
          required: true
          description: IndoorAtlas venue ID
      tags:
        - Venues
      responses:
        '200':
          description: Information for the requested venue and all of its mapped floor plans, geofences and POIs (only floor plans for which maps have been generated are included)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Venue"
        '404':
          description: No mapped venue found with given ID
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        '429':
          $ref: "#/components/responses/TooManyRequests"
        default:
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /venues:
    get:
      summary: List all venues
      description: Get information for all venues with any mapped floor plans.
      tags:
        - Venues
      responses:
        '200':
          description: Information for all mapped venues. Floor plan, geofence and POI information is not included, but the venue has to have at least one floor plan for which a map has been generated before the venue is included.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/SimpleVenue"
        '404':
          description: No venues found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        '429':
          $ref: "#/components/responses/TooManyRequests"
        default:
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

components:
  securitySchemes:
    apikey:
      type: apiKey
      name: key
      in: query

  headers:
    X-RateLimit-Limit:
      description: The total number of allowed requests in a rate limit period.
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Number of remaining allowed requests in the current rate limit period.
      schema:
        type: integer
    X-RateLimit-Reset:
      description: The time when rate limit period is reset.
      schema:
        type: string
        format: dateTime

  responses:
    TooManyRequests:
      description: API rate limit reached. Making requets should be halted until the rate limit period resets.
      headers:
        Retry-After:
          description: Duration in seconds after which the API can be accessed again.
          schema:
            type: integer
        X-RateLimit-Limit:
          $ref: "#/components/headers/X-RateLimit-Limit"
        X-RateLimit-Remaining:
          $ref: "#/components/headers/X-RateLimit-Remaining"
        X-RateLimit-Reset:
          $ref: "#/components/headers/X-RateLimit-Reset"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"

  schemas:
    WifiObservation:
      type: object
      required:
        - macAddress
      properties:
        macAddress:
          type: string
          description: The MAC address (BSSID) of the wireless access point. The addresses are expected in format "00:00:00:00:00:00"
          pattern: ^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$
        signalStrength:
          type: number
          nullable: true
          maximum: 0
          minimum: -100
          description: Measured signal strength (RSSI) in dBm. If signal strength is not known use either `0` or `null` . It's also acceptable to not include the property at all.
      example:
        macAddress: "80:e6:50:21:42:72"
        signalStrength: -43

    IBeaconObservation:
      type: object
      required:
        - uuid
        - major
        - minor
      properties:
        uuid:
          type: string
          description: Proximity UUID
          pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$
        major:
          type: number
          description: Major code
        minor:
          type: number
          description: Minor code
        signalStrength:
          type: number
          nullable: true
          maximum: 0
          minimum: -100
          description: Measured signal strength (RSSI) in dBm. If signal strength is not known use either `0` or `null` . It's also acceptable to not include the property at all.
      example:
        uuid: "b9407f30-f5f8-466e-aff9-25556b57fe6d"
        major: 123
        minor: 234
        signalStrength: -92

    LocateRequest:
      type: object
      description: Access points from a Wi-Fi scan and/or iBeacons from a BLE scan
      properties:
        wifis:
          type: array
          items:
            $ref: "#/components/schemas/WifiObservation"
        iBeacons:
          type: array
          items:
            $ref: "#/components/schemas/IBeaconObservation"

    Coordinate:
      properties:
        lat:
          type: number
          maximum: 90
          minimum: -90
          description: Latitude in degrees
        lon:
          type: number
          maximum: 180
          minimum: -180
          description: Longitude in degrees
      required:
        - lat
        - lon
      example:
        lat: 60.1672065
        lon: 24.943796

    LocateResponse:
      type: object
      properties:
        location:
          description: Estimated location. The property is available only if location was determined.
          properties:
            coordinates:
              $ref: "#/components/schemas/Coordinate"
            accuracy:
              type: number
              description: Uncertainty of position estimate in meters
            floorNumber:
              type: integer
              description: Estimated floor number. Not available if floor number cannot be determined
        context:
          type: object
          description: Estimated context.  Not available if context cannot be determined
          properties:
            indooratlas:
              type: object
              description: IndoorAtlas provided context. Not available if cannot be determined
              properties:
                venueId:
                  type: string
                  format: uuid
                  description: IndoorAtlas venue ID. Not available if venue cannot be determined
                floorPlanId:
                  type: string
                  format: uuid
                  description: IndoorAtlas floor plan ID. Not available if floor plan cannot be determined

    FloorPlan:
      type: object
      description: Floor plan information
      required:
        - id
        - venueId
        - name
        - floorNumber
      properties:
        id:
          type: string
          format: uuid
          description: Floor plan ID
        venueId:
          type: string
          format: uuid
          description: Venue ID
        name:
          type: string
          description: Floor plan name
        floorNumber:
          type: integer
          format: int32
          description: Floor number
        image:
          type: object
          description: Floor plan image information. May not be available if floor plan is imported from 3rd party source
          required:
            - url
            - width
            - height
            - widthMeters
            - heightMeters
            - metersToPixels
            - pixelsToMeters
            - center
            - bearing
            - topLeft
            - topRight
            - bottomLeft
            - bottomRight
          properties:
            url:
              type: string
              description: URL to floor plan image. NOTE! the image url may expire and change between requests. Do not count on it to work indefinitely
            width:
              type: integer
              format: int32
              description: Width of floor plan image in pixels
            height:
              type: integer
              format: int32
              description: Height of floor plan image in pixels
            widthMeters:
              type: number
              format: double
              description: Width of floor plan image placed on the surface of earth in meters
            heightMeters:
              type: number
              format: double
              description: Height of floor plan image placed on the surface of earth in meters
            metersToPixels:
              type: number
              format: double
              description: Meters to pixels conversion factor. Multiply distance in meters by this factor to get distance in pixels
            pixelsToMeters:
              type: number
              format: double
              description: Pixels to meters conversion factor. Multiply distance in pixels by this factor to get distance in meters
            center:
              allOf:
                - description: Corresponding WGS84 coordinate of center of floor plan image placed on the surface of earth
                - $ref: "#/components/schemas/Coordinate"
            bearing:
              type: number
              format: double
              description: The bearing of left side of floor plan image in degrees East of true North (i.e. clockwise rotation) in range [0, 360]
            topLeft:
              allOf:
                - description: Corresponding WGS84 coordinate of top left corner of floor plan image placed on the surface of earth
                - $ref: "#/components/schemas/Coordinate"
            topRight:
              allOf:
                - description: Corresponding WGS84 coordinate of top right corner of floor plan image placed on the surface of earth
                - $ref: "#/components/schemas/Coordinate"
            bottomLeft:
              allOf:
                - description: Corresponding WGS84 coordinate of bottom left corner of floor plan image placed on the surface of earth
                - $ref: "#/components/schemas/Coordinate"
            bottomRight:
              allOf:
                - description: Corresponding WGS84 coordinate of bottom right corner of floor plan image placed on the surface of earth
                - $ref: "#/components/schemas/Coordinate"

    SimpleVenue:
      type: object
      description: Venue details excluding floor plans, geofences or POIs
      required:
        - id
        - name
        - coordinates
      properties:
        id:
          type: string
          format: uuid
          description: Venue ID
        name:
          type: string
          description: Venue name
        coordinates:
          allOf:
            - description: WGS84 coordinates of venue
            - $ref: "#/components/schemas/Coordinate"

    Venue:
      type: object
      description: Venue details including floor plans, geofence and POIs
      required:
        - id
        - name
        - coordinates
      properties:
        id:
          type: string
          format: uuid
          description: Venue ID
        name:
          type: string
          description: Venue name
        coordinates:
          allOf:
            - description: WGS84 coordinates of venue
            - $ref: "#/components/schemas/Coordinate"
        floorPlans:
          type: array
          description: List of mapped floor plans for the venue
          items:
            $ref: "#/components/schemas/FloorPlan"
        geofences:
          type: array
          description: List of geofences for the venue
          items:
            $ref: "#/components/schemas/Geofence"
        pois:
          type: array
          description: List of POIs for the venue
          items:
            $ref: "#/components/schemas/POI"

    Geofence:
      type: object
      description: Geofence details. See https://github.com/IndoorAtlas/cordova-plugin/blob/master/www/Geofence.js#L50 for an example how to convert to GeoJSON (note the differences in property names)
      required:
        - id
        - name
        - floorNumber
        - coordinates
      properties:
        id:
          type: string
          description: Geofence ID
        name:
          type: string
          description: Geofence name
        floorNumber:
          type: integer
          format: int32
          description: Floor number
        coordinates:
          type: array
          items:
            $ref: "#/components/schemas/Coordinate"
          description: WGS84 coordinates of the vertices of the geofence polygon
        payload:
          type: object
          description: Free-form JSON payload

    POI:
      type: object
      description: POI details. See https://github.com/IndoorAtlas/cordova-plugin/blob/master/www/POI.js#L44 for an example how to convert to GeoJSON (note the differences in property names)
      required:
        - id
        - name
        - floorNumber
        - coordinates
      properties:
        id:
          type: string
          description: POI ID
        name:
          type: string
          description: POI name
        floorNumber:
          type: integer
          format: int32
          description: Floor number
        coordinates:
          allOf:
            - description: WGS84 coordinates of POI
            - $ref: "#/components/schemas/Coordinate"
        payload:
          type: object
          description: Free-form JSON payload

    Error:
      properties:
        message:
          type: string
      example:
        message: Request body should be JSON object

    UnprocessableRequestError:
      properties:
        message:
          type: string
          description: Human readable error message
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
                description: Field which failed the validation
              error:
                type: string
                description: Validation error
      example:
        message: Validation failed
        errors:
          - error: Value should be greater than -180
            field: '.latitude'
