swagger: "2.0"
info:
  title: Mainflux things service
  description: HTTP API for managing platform things and channels.
  version: "1.0.0"
consumes:
  - "application/json"
produces:
  - "application/json"
paths:
  /things:
    post:
      summary: Adds new thing
      description: |
        Adds new thing to the list of things owned by user identified using
        the provided access token.
      tags:
        - things
      parameters:
        - $ref: "#/parameters/Authorization"
        - name: thing
          description: JSON-formatted document describing the new thing.
          in: body
          schema:
            $ref: "#/definitions/CreateThingReq"
          required: true
      responses:
        201:
          description: Thing registered.
          headers:
            Location:
              type: string
              description: Created thing's relative URL (i.e. /things/{thingId}).
        400:
          description: Failed due to malformed JSON.
        403:
          description: Missing or invalid access token provided.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
    get:
      summary: Retrieves managed things
      description: |
        Retrieves a list of managed things. Due to performance concerns, data
        is retrieved in subsets. The API things must ensure that the entire
        dataset is consumed either by making subsequent requests, or by
        increasing the subset size of the initial request.
      tags:
        - things
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/Limit"
        - $ref: "#/parameters/Offset"
        - $ref: "#/parameters/Name"
        - $ref: "#/parameters/Metadata"
      responses:
        200:
          description: Data retrieved.
          schema:
            $ref: "#/definitions/ThingsPage"
        400:
          description: Failed due to malformed query parameters.
        403:
          description: Missing or invalid access token provided.
        500:
          $ref: "#/responses/ServiceError"
  /things/bulk:
    post:
      summary: Bulk provisions new things
      description: |
        Adds new things to the list of things owned by user identified using
        the provided access token.
      tags:
        - things
      parameters:
        - $ref: "#/parameters/Authorization"
        - name: things
          description: JSON-formatted document describing the new things.
          in: body
          schema:
            $ref: "#/definitions/CreateThingsReq"
          required: true
      responses:
        201:
          description: Things registered.
        400:
          description: Failed due to malformed JSON.
        403:
          description: Missing or invalid access token provided.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
  /channels/{chanId}/things:
    get:
      summary: Retrieves list of things connected to specified channel
      description: |
        Retrieves list of things connected to specified channel with pagination
        metadata.
      tags:
        - things
      parameters:
        - $ref: "#/parameters/ChanId"
        - $ref: "#/parameters/Offset"
        - $ref: "#/parameters/Limit"
      responses:
        200:
          description: Data retrieved.
          schema:
            $ref: "#/definitions/ThingsPage"
        400:
          description: Failed due to malformed query parameters.
        403:
          description: Missing or invalid access token provided.
        500:
          $ref: "#/responses/ServiceError"
  /things/{thingId}:
    get:
      summary: Retrieves thing info
      tags:
        - things
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ThingId"
      responses:
        200:
          description: Data retrieved.
          schema:
            $ref: "#/definitions/ThingRes"
        403:
          description: Missing or invalid access token provided.
        404:
          description: Thing does not exist.
        500:
          $ref: "#/responses/ServiceError"
    put:
      summary: Updates thing info
      description: |
        Update is performed by replacing the current resource data with values
        provided in a request payload. Note that the thing's type and ID
        cannot be changed.
      tags:
        - things
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ThingId"
        - name: thing
          description: JSON-formatted document describing the updated thing.
          in: body
          schema:
            $ref: "#/definitions/UpdateThingReq"
          required: true
      responses:
        200:
          description: Thing updated.
        400:
          description: Failed due to malformed JSON.
        403:
          description: Missing or invalid access token provided.
        404:
          description: Thing does not exist.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
    delete:
      summary: Removes a thing
      description: |
        Removes a thing. The service will ensure that the removed thing is
        disconnected from all of the existing channels.
      tags:
        - things
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ThingId"
      responses:
        204:
          description: Thing removed.
        400:
          description: Failed due to malformed thing's ID.
        403:
          description: Missing or invalid access token provided.
        500:
          $ref: "#/responses/ServiceError"
  /things/{thingId}/key:
    patch:
      summary: Updates thing key
      description: |
        Update is performed by replacing current key with a new one.
      tags:
        - things
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ThingId"
        - name: key
          description: JSON-formatted document describing updated key.
          in: body
          schema:
            $ref: "#/definitions/UpdateKeyReq"
          required: true
      responses:
        200:
          description: Thing key updated.
        400:
          description: Failed due to malformed JSON.
        403:
          description: Missing or invalid access token provided.
        404:
          description: Thing does not exist.
        409:
          description: Specified key already exists.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
  /channels:
    post:
      summary: Creates new channel
      description: |
        Creates new channel. User identified by the provided access token will
        be the channel's owner.
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/Authorization"
        - name: channel
          description: JSON-formatted document describing the new channel.
          in: body
          schema:
            $ref: "#/definitions/ChannelReq"
          required: true
      responses:
        201:
          description: Channel created.
          headers:
            Location:
              type: string
              description: Created channel's relative URL (i.e. /channels/{chanId}).
        400:
          description: Failed due to malformed JSON.
        403:
          description: Missing or invalid access token provided.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
    get:
      summary: Retrieves managed channels
      description: |
        Retrieves a list of managed channels. Due to performance concerns, data
        is retrieved in subsets. The API things must ensure that the entire
        dataset is consumed either by making subsequent requests, or by
        increasing the subset size of the initial request.
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/Limit"
        - $ref: "#/parameters/Offset"
        - $ref: "#/parameters/Name"
      responses:
        200:
          description: Data retrieved.
          schema:
            $ref: "#/definitions/ChannelsPage"
        400:
          description: Failed due to malformed query parameters.
        403:
          description: Missing or invalid access token provided.
        500:
          $ref: "#/responses/ServiceError"
  /channels/bulk:
    post:
      summary: Bulk provisions new channels
      description: |
        Adds new channels to the list of channels owned by user identified using
        the provided access token.
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/Authorization"
        - name: channels
          description: JSON-formatted document describing the new channels.
          in: body
          schema:
            $ref: "#/definitions/CreateChannelsReq"
          required: true
      responses:
        201:
          description: Channels registered.
        400:
          description: Failed due to malformed JSON.
        403:
          description: Missing or invalid access token provided.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
  /channels/{chanId}:
    get:
      summary: Retrieves channel info
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ChanId"
      responses:
        200:
          description: Data retrieved.
          schema:
            $ref: "#/definitions/ChannelRes"
        403:
          description: Missing or invalid access token provided.
        404:
          description: Channel does not exist.
        500:
          $ref: "#/responses/ServiceError"
    put:
      summary: Updates channel info
      description: |
        Update is performed by replacing the current resource data with values
        provided in a request payload. Note that the channel's ID will not be
        affected.
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ChanId"
        - name: channel
          description: JSON-formatted document describing the updated channel.
          in: body
          schema:
            $ref: "#/definitions/ChannelReq"
          required: true
      responses:
        200:
          description: Channel updated.
        400:
          description: Failed due to malformed JSON.
        403:
          description: Missing or invalid access token provided.
        404:
          description: Channel does not exist.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
    delete:
      summary: Removes a channel
      description: |
        Removes a channel. The service will ensure that the subscribed apps and
        things are unsubscribed from the removed channel.
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ChanId"
      responses:
        204:
          description: Channel removed.
        400:
          description: Failed due to malformed channel's ID.
        403:
          description: Missing or invalid access token provided.
        500:
          $ref: "#/responses/ServiceError"
  /things/{thingId}/channels:
    get:
      summary: Retrieves list of channels connected to specified thing
      description: |
        Retrieves list of channels connected to specified thing with pagination
        metadata.
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/ThingId"
        - $ref: "#/parameters/Offset"
        - $ref: "#/parameters/Limit"
      responses:
        200:
          description: Data retrieved.
          schema:
            $ref: "#/definitions/ChannelsPage"
        400:
          description: Failed due to malformed query parameters.
        403:
          description: Missing or invalid access token provided.
        500:
          $ref: "#/responses/ServiceError"
  /channels/{chanId}/things/{thingId}:
    put:
      summary: Connects the thing to the channel
      description: |
        Creates connection between a thing and a channel. Once connected to
        the channel, things are allowed to exchange messages through it.
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ChanId"
        - $ref: "#/parameters/ThingId"
      responses:
        200:
          description: Thing connected.
        403:
          description: Missing or invalid access token provided.
        404:
          description: Channel or thing does not exist.
        500:
          $ref: "#/responses/ServiceError"
    delete:
      summary: Disconnects the thing from the channel
      description: |
        Removes connection between a thing and a channel. Once connection is
        removed, thing can no longer exchange messages through the channel.
      tags:
        - channels
      parameters:
        - $ref: "#/parameters/Authorization"
        - $ref: "#/parameters/ChanId"
        - $ref: "#/parameters/ThingId"
      responses:
        204:
          description: Thing disconnected.
        403:
          description: Missing or invalid access token provided.
        404:
          description: Channel or thing does not exist.
        500:
          $ref: "#/responses/ServiceError"
  /channels/{chanId}/access:
    post:
      summary: Checks if thing has access to a channel.
      description: |
        Checks if a thing with a specified key has an access to a specified
        channel and if it has, it returns that things id.
      tags:
        - access
      parameters:
        - $ref: "#/parameters/ChanId"
        - name: token
          description: JSON-formatted document that contains thing key.
          in: body
          schema:
            $ref: "#/definitions/IdentityReq"
          required: true
      responses:
        200:
          description: |
            Thing has access to the specified channel and the thing ID is returned.
          schema:
            $ref: "#/definitions/Identity"
        403:
          description: |
            Thing and channel are not connected, or thing with specified key doesn't
            exist.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
  /channels/{chanId}/access-by-id:
    post:
      summary: Checks if thing has access to a channel.
      description: |
        Checks if a thing with a specified ID has an access to a specified
        channel.
      tags:
        - access
      parameters:
        - $ref: "#/parameters/ChanId"
        - name: token
          description: JSON-formatted document that contains thing key.
          in: body
          schema:
            $ref: "#/definitions/AccessByIDReq"
          required: true
      responses:
        200:
          description: Thing has access to the specified channel.
        403:
          description: |
            Thing and channel are not connected, or thing with specified ID doesn't
            exist.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"
  /identify:
    post:
      summary: Validates thing's key and returns it's ID if key is valid.
      description: |
        Validates thing's key and returns it's ID if specified key exists
        and is valid.
      tags:
        - identity
      parameters:
        - name: token
          description: JSON-formatted document that contains thing key.
          in: body
          schema:
            $ref: "#/definitions/IdentityReq"
          required: true
      responses:
        200:
          description: Thing ID returned.
          schema:
            $ref: "#/definitions/Identity"
        403:
          description: Thing with specified key doesn't exist.
        415:
          description: Missing or invalid content type.
        500:
          $ref: "#/responses/ServiceError"

parameters:
  Authorization:
    name: Authorization
    description: User's access token.
    in: header
    type: string
    required: true
  ChanId:
    name: chanId
    description: Unique channel identifier.
    in: path
    type: integer
    minimum: 1
    required: true
  ThingId:
    name: thingId
    description: Unique thing identifier.
    in: path
    type: integer
    minimum: 1
    required: true
  Limit:
    name: limit
    description: Size of the subset to retrieve.
    in: query
    type: integer
    default: 10
    maximum: 100
    minimum: 1
    required: false
  Offset:
    name: offset
    description: Number of items to skip during retrieval.
    in: query
    type: integer
    default: 0
    minimum: 0
    required: false
  Name:
    name: name
    description: Name filter. Filtering is performed as a case-insensitive partial match.
    in: query
    type: string
    minimum: 0
    required: false
  Metadata:
    name: metadata
    description: Metadata filter. Filtering is performed matching the parameter with metadata on top level. Parameter is json.
    in: query
    type: string
    minimum: 0
    required: false

responses:
  ServiceError:
    description: Unexpected server-side error occurred.

definitions:
  ChannelsPage:
    type: object
    properties:
      channels:
        type: array
        minItems: 0
        uniqueItems: true
        items:
          $ref: "#/definitions/ChannelRes"
      total:
        type: integer
        description: Total number of items.
      offset:
        type: integer
        description: Number of items to skip during retrieval.
      limit:
        type: integer
        description: Maximum number of items to return in one page.
    required:
      - channels
  ChannelRes:
    type: object
    properties:
      id:
        type: string
        description: Unique channel identifier generated by the service.
      name:
        type: string
        description: Free-form channel name.
      metadata:
        type: object
        description: Arbitrary, object-encoded channel's data.
    required:
      - id
  ChannelReq:
    type: object
    properties:
      name:
        type: string
        description: Free-form channel name.
      metadata:
        type: object
        description: Arbitrary, object-encoded channel's data.
  ThingsPage:
    type: object
    properties:
      things:
        type: array
        minItems: 0
        uniqueItems: true
        items:
          $ref: "#/definitions/ThingRes"
      total:
        type: integer
        description: Total number of items.
      offset:
        type: integer
        description: Number of items to skip during retrieval.
      limit:
        type: integer
        description: Maximum number of items to return in one page.
    required:
      - things
  ThingRes:
    type: object
    properties:
      id:
        type: string
        description: Unique thing identifier generated by the service.
      name:
        type: string
        description: Free-form thing name.
      key:
        type: string
        description: Auto-generated access key.
      metadata:
        type: object
        description: Arbitrary, object-encoded thing's data.
    required:
      - id
      - type
      - key
  CreateThingReq:
    type: object
    properties:
      key:
        type: string
        description: |
          Thing key that is used for thing auth. If there is
          not one provided service will generate one in UUID
          format.
      name:
        type: string
        description: Free-form thing name.
      metadata:
        type: object
        description: Arbitrary, object-encoded thing's data.
  UpdateThingReq:
    type: object
    properties:
      name:
        type: string
        description: Free-form thing name.
      metadata:
        type: object
        description: Arbitrary, object-encoded thing's data.
  UpdateKeyReq:
    type: object
    properties:
      key:
        type: string
        description: Thing key that is used for thing auth.
  IdentityReq:
    type: object
    properties:
      token:
        type: string
        description: Thing key that is used for thing auth.
    required:
      - token
  AccessByIDReq:
    type: object
    properties:
      thing_id:
        type: string
        description: Thing ID by which thing is uniquely identified.
  Identity:
    type: object
    properties:
      id:
        type: string
        description: Thing unique identifier.
