swagger: "2.0"
schemes:
  - https
host: api.feedback.eu.pendo.io
info:
  contact:
    email: support@receptive.io
    name: Feedback Support
    x-twitter: receptiveio
  description: |-
    ## Who is this for?

    This documentation is for developers creating their own integration with [Feedback's](https://www.pendo.io/product/feedback/) API. If you are doing a standard integration, there's a really easy [Javascript integration](https://help.receptive.io/hc/en-us/articles/209221969-How-to-integrate-Receptive-with-your-app) that you should know about before you go to the effort of building your own integration.

    ## Authentication

    API calls generally need to be authenticated. Generate an API Key at https://feedback.pendo.io/app/#/vendor/settings?section=integrate. This key should then be added to every request as a request header named 'auth-token' (preferred), or as a query parameter named 'auth-token'.

    ## Endpoint

    API endpoint is https://api.feedback.eu.pendo.io / https://api.feedback.us.pendo.io depending where your datacenter is located.

    ## Notes

    API endpoints are being added to this documentation as needed by customers. If you don't see an endpoint you need please contact support and if it exists we'll publish the docs here. The 'try it out' feature on this documentation page will probably be blocked by your browser because the Access-Control-Allow-Origin header has its value set by the Feedback server depending on your hostname.

    ## Generating client code

    This documentation is automatically generated from an OpenAPI spec available [here](http://apidoc.receptive.io/receptive.swagger.json). You can use Swagger to auto-generate API client code in many languages using the [Swagger Editor](http://editor.swagger.io/#/)
  title: Pendo Feedback API
  version: 1.0.0
  x-apisguru-categories:
    - ecommerce
  x-logo:
    url: https://twitter.com/receptiveio/profile_image?size=original
  x-origin:
    - format: swagger
      url: http://apidoc.receptive.io/receptive.swagger.json
      version: "2.0"
  x-providerName: pendo.io
produces:
  - application/json
securityDefinitions:
  userApiKey (query parameter):
    description: Generate an API Key at https://feedback.pendo.io/app/#/vendor/settings?section=integrate. This key should then be added to every request URL as a query parameter.
    in: query
    name: auth-token
    type: apiKey
  userApiKey (request header):
    description: Generate an API Key at https://feedback.pendo.io/app/#/vendor/settings?section=integrate. This key should then be added to every request as a request header.
    in: header
    name: auth-token
    type: apiKey
security:
  - userApiKey (request header): []
  - userApiKey (query parameter): []
parameters:
  accountIdInPath:
    description: Account ID (generated by Feedback)
    in: path
    name: id
    required: true
    type: number
  limit:
    description: Limit the number of records returned
    in: query
    minimum: 0
    name: limit
    required: false
    type: number
  order_by:
    description: The field to use for sort
    in: query
    name: order_by
    required: false
    type: string
  order_dir:
    description: The sort direction
    enum:
      - asc
      - desc
    in: query
    name: order_dir
    required: false
    type: string
  start:
    description: Offset to start at
    in: query
    minimum: 0
    name: start
    required: false
    type: number
responses:
  "410":
    description: Resource has been deleted
    headers:
      status:
        enum:
          - "410"
        type: integer
paths:
  /accounts:
    get:
      parameters:
        - $ref: "#/parameters/limit"
        - $ref: "#/parameters/start"
        - $ref: "#/parameters/order_dir"
        - description: The field to use for sort
          enum:
            - churned
            - last_seen
            - name
          in: query
          name: order_by
          required: false
          type: string
      responses:
        "200":
          description: Success
          schema:
            items:
              $ref: "#/definitions/Account"
            type: array
      summary: Query accounts
      tags:
        - account
  "/accounts/{id}":
    delete:
      description: This removes most traces of an Accounts existence from the system.
      parameters:
        - in: path
          name: id
          required: true
          type: number
      responses:
        "200":
          description: the deleted Account
          schema:
            $ref: "#/definitions/Account"
      summary: Delete an Account
      tags:
        - account
    get:
      parameters:
        - $ref: "#/parameters/accountIdInPath"
      responses:
        "200":
          description: an Account
          schema:
            $ref: "#/definitions/Account"
        "410":
          $ref: "#/responses/410"
      summary: Get an Account
      tags:
        - account
    put:
      parameters:
        - $ref: "#/parameters/accountIdInPath"
        - description: Updated Account values
          in: body
          name: account
          schema:
            properties:
              monthly_value:
                format: float
                type: number
              name:
                type: string
              status:
                enum:
                  - paying
                  - prospect
                  - not_paying
                type: string
            type: object
      responses:
        "200":
          description: Success
      summary: Update an Account
      tags:
        - account
  "/accounts/{id}/tags":
    delete:
      description: Removes all custom tags associated with the Account
      parameters:
        - $ref: "#/parameters/accountIdInPath"
      responses:
        "200":
          description: success
      summary: Delete custom Account tags
      tags:
        - account
    get:
      parameters:
        - $ref: "#/parameters/accountIdInPath"
      responses:
        "200":
          description: |-
            Returns an array of maps specifying tags under each tag group, for example:

            [

            {'impacts' => ['sales']},

            {'resources' => ['dev', 'test', 'support']}

            ]
        "404":
          description: Account not found
      summary: Get custom Account tags
      tags:
        - account
    post:
      parameters:
        - $ref: "#/parameters/accountIdInPath"
        - description: |-
            An array of maps specifying tags under each tag group, for example:

            [

            {'impacts' => ['sales']},

            {'resources' => ['dev', 'test', 'support']}

            ]
          in: body
          name: tags
          required: true
          schema:
            $ref: "#/definitions/Tags"
      responses:
        "200":
          description: Updated Account tags
        "404":
          description: Account not found
      summary: Overwrite current custom Account tags with the given tags
      tags:
        - account
  /comments:
    get:
      description: get a list of Comment records
      parameters:
        - description: case_id
          in: query
          name: case_id
          required: true
          type: integer
      responses:
        "200":
          description: Comment records
          schema:
            items:
              $ref: "#/definitions/Comment"
            type: array
      summary: fetch Comment records
      tags:
        - comment
  /features:
    get:
      parameters:
        - $ref: "#/parameters/limit"
        - $ref: "#/parameters/start"
        - $ref: "#/parameters/order_dir"
        - description: Filter by whether the features are shown/hidden from customer, if supplied.
          in: query
          name: is_private
          required: false
          type: boolean
        - description: Filter by User ID, if supplied.
          in: query
          name: wanted_by
          required: false
          type: integer
        - description: The field to use for sort
          enum:
            - title
            - created_at
            - updated_at
            - declined_at
            - developing_at
            - planned_at
            - released_at
            - waiting_at
            - deleted_at
          in: query
          name: order_by
          required: false
          type: string
        - description: Tags to limit results by. Multiple tags can be provided via comma delimeted string. Tags with contexts can be used. E.g. "....&tags=TagExample,Multi:TagThis,Multi:TagThat".
          in: query
          name: tags
          required: false
          type: string
        - description: Products to limit results by. Comma delimeted string of either ids or names. E.g. "...&products=1,2,3" or "...products=Product1,Product2".
          in: query
          name: products
          required: false
          type: string
      responses:
        "200":
          description: Success
          schema:
            items:
              $ref: "#/definitions/Feature"
            type: array
      summary: Query features
      tags:
        - feature
  "/features/{id}":
    get:
      parameters:
        - description: ID of the feature
          in: path
          name: id
          required: true
          type: integer
      responses:
        "200":
          description: ok
          schema:
            $ref: "#/definitions/Feature"
      summary: Get a Feature by ID
      tags:
        - feature
  "/features/{id}/tags":
    delete:
      description: Removes all custom tags associated with the Feature
      parameters:
        - description: Feedback's Feature ID
          in: path
          name: id
          required: true
          type: number
      responses:
        "200":
          description: success
      summary: Delete custom Feature tags
      tags:
        - feature
    get:
      parameters:
        - $ref: "#/parameters/accountIdInPath"
      responses:
        "200":
          description: |-
            Returns an array of maps specifying tags under each tag group, for example:

            [

            {'impacts' => ['sales']},

            {'resources' => ['dev', 'test', 'support']}

            ]
        "404":
          description: Feature not found
      summary: Get custom Feature tags
      tags:
        - feature
    post:
      parameters:
        - description: Feedback's Feature ID
          in: path
          name: id
          required: true
          type: number
        - in: body
          name: tags
          required: true
          schema:
            $ref: "#/definitions/Tags"
      responses:
        "200":
          description: Updated Feature tags
        "404":
          description: Feature not found
      summary: Overwrite current custom Feature tags with the given tags
      tags:
        - feature
  /health-check/ping:
    get:
      description: Provides a response for automatic checks that the API and load balancers are healthy
      responses:
        "200":
          description: API is healthy
        "503":
          description: Load balancers cannot route a request to a healthy API server
      security: []
      summary: Health check for API
      tags:
        - system
  /hooks:
    post:
      description: Use this endpoint to subscribe to webhooks.
      parameters:
        - in: body
          name: data
          required: true
          schema:
            properties:
              event:
                description: |-
                  The event field can contain one of the following values-
                  1) 'feature_created' - When a new feature is created a webhook will be triggered with the details of the feature. Feature details can be found in the model section under Feature object
                  2) 'feature_status_changed' - When a feature status is updated a webhook will be triggered with the updated Feature details. Feature details can be found in the model section under Feature object.
                  3) 'feature_comment_created' - When a commment is created on a feature, a webhook will be triggered with the details about the Feature and the new comment. Feature and Comment details can be found in the model section under Feature object and Comment object.
                type: string
              target_url:
                description: The target URL where the events will be sent to.
                type: string
            type: object
      responses:
        "200":
          description: Successfully subscribed to the weebhooks
      summary: Subscribe to webhooks
      tags:
        - hooks
  /hooks/unsubscribe:
    post:
      description: Use this endpoint to unsubscribe from a webhook
      parameters:
        - in: body
          name: data
          required: true
          schema:
            properties:
              target_url:
                type: string
            type: object
      responses:
        "200":
          description: Successfully unsubscribed from the weebhooks
      summary: Unsubscribe from webhooks
      tags:
        - hooks
  /search:
    get:
      parameters:
        - description: Specifies the type of entity being searched for. Must be set to 'feature'
          enum:
            - feature
          in: query
          name: scope
          required: true
          type: string
        - description: The search term.
          in: query
          name: q
          required: true
          type: string
        - description: "A comma seperated list of status values to filter by, if required. Valid values: 'new', 'waiting', 'planned', 'developing', 'released', 'declined'."
          enum:
            - new
            - waiting
            - planned
            - developing
            - released
            - declined
          in: query
          name: status
          required: false
          type: string
        - description: Tags to limit results by - only applies when scope is 'case' or 'feature'. Multiple tags can be provided via comma delimeted string. Tags with contexts can be used. E.g. "....&tags=TagExample,Multi:TagThis,Multi:TagThat".
          in: query
          name: tags
          required: false
          type: string
        - description: Products to limit results by. Comma delimeted string of either ids or names. E.g. "...&products=1,2,3" or "...products=Product1,Product2".
          in: query
          name: products
          required: false
          type: string
      responses:
        "200":
          description: Success
          schema:
            items:
              $ref: "#/definitions/Feature"
            type: array
      summary: Search features
      tags:
        - feature
  /users:
    get:
      description: get a list of User records
      parameters:
        - description: role
          enum:
            - endUser
            - vendorUser
          in: query
          name: role
          required: true
          type: string
        - description: Filter by Account ID, if supplied. Only useful if role param is endUser
          in: query
          name: account
          required: false
          type: integer
        - default: 0
          description: Offset to start at
          in: query
          minimum: 0
          name: start
          required: false
          type: integer
        - default: 300
          description: Limit the number of records returned. Max value can be 300. If limit is set to more than 300 the api will return an error
          in: query
          name: limit
          required: false
          type: integer
        - $ref: "#/parameters/order_by"
        - $ref: "#/parameters/order_dir"
      responses:
        "200":
          description: User records
          schema:
            items:
              $ref: "#/definitions/User"
            type: array
      summary: fetch User records
      tags:
        - user
    post:
      consumes:
        - application/json
      description: Replicates much of the functionality of the widget ping, allowing callers to create or update User records for End Users. If you call this with a new User and/or Account, the record will be created. If you call for an existing User/Account, the record will be updated. You can also call this at EndUser login time, or more frequently, to notify Feedback that the EndUser has been seen. This keeps Feedback's 'last seen' data fresh and updates your reporting. This endpoint is used by our Zapier integration. The only value allowed in user.roles is 'endUser'. The id you supply here for the User and Account should be your own unique id, which Feedback calls external_id. This probably isn't the same as Feedback's id seen elsewhere in the API.
      parameters:
        - description: the account and user
          in: body
          name: data
          required: true
          schema:
            $ref: "#/definitions/EndUserPing"
      responses:
        "200":
          description: Success
      summary: Ping to create or update an EndUser and Account in one call
      tags:
        - user
  /users/invite_end_user:
    post:
      parameters:
        - in: body
          name: data
          required: true
          schema:
            properties:
              account_external_id:
                type: string
              account_name:
                type: string
              account_status:
                enum:
                  - prospect
                  - not_paying
                  - paying
                type: string
              email:
                type: string
              full_name:
                type: string
              monthly_value:
                format: float
                type: number
              send_invite:
                type: boolean
              user_external_id:
                type: string
            required:
              - account_status
            type: object
      responses:
        "200":
          description: success
      summary: Invite an EndUser (customer)
      tags:
        - user
  /users/invite_vendor_user:
    post:
      consumes:
        - application/json
      parameters:
        - in: body
          name: data
          required: true
          schema:
            properties:
              email:
                type: string
              external_id:
                type: string
              full_name:
                type: string
              permission_group_id:
                format: integer
                type: number
              team:
                type: string
            required:
              - email
              - full_name
            type: object
      responses:
        "200":
          description: success
      summary: Invite a VendorUser (Team member)
      tags:
        - user
        - team
  /users/search:
    get:
      parameters:
        - description: Find using your external ID, rather than the ID generated by Feedback
          in: query
          name: external_id
          required: false
          type: string
        - description: Find user by their email address. Role param must be specified when using this option
          in: query
          name: email
          required: false
          type: string
        - description: Users role ('vendorUser' or 'endUser'). Only useful when finding a user by their email address
          enum:
            - endUser
            - vendorUser
          in: query
          name: role
          type: string
      responses:
        "200":
          description: the User record
          schema:
            $ref: "#/definitions/User"
        "410":
          description: User has been deleted
      summary: Find a User with a query
      tags:
        - user
  "/users/{id}":
    delete:
      description: This removes most traces of a User's existence from the system. For an EndUser you might want to consider just letting them churn after a period of inactivity.
      parameters:
        - in: path
          name: id
          required: true
          type: number
      responses:
        "200":
          description: the deleted User
          schema:
            $ref: "#/definitions/User"
      summary: Delete a User
      tags:
        - user
    get:
      parameters:
        - in: path
          name: id
          required: true
          type: number
      responses:
        "200":
          description: the User record
          schema:
            $ref: "#/definitions/User"
        "410":
          description: User has been deleted
      summary: Get a User record
      tags:
        - user
    put:
      parameters:
        - description: Feedback's User ID
          in: path
          name: id
          required: true
          type: number
        - in: body
          name: user
          schema:
            properties:
              email:
                type: string
              external_id:
                type: string
              name:
                type: string
              permission_group_id:
                description: only valid for users with role 'vendorUser'
                format: integer
                type: number
            type: object
      responses:
        "200":
          description: updated User
          schema:
            $ref: "#/definitions/User"
      summary: Update a User
      tags:
        - user
  "/users/{id}/tags":
    delete:
      description: Removes all custom tags associated with the User
      parameters:
        - description: Feedback's User ID
          in: path
          name: id
          required: true
          type: number
      responses:
        "200":
          description: success
      summary: Delete custom User tags
      tags:
        - user
    get:
      parameters:
        - description: Feedback's User ID
          in: path
          name: id
          required: true
          type: number
      responses:
        "200":
          description: |-
            Returns an array of maps specifying tags under each tag group, for example:

            [

            {'impacts' => ['sales']},

            {'resources' => ['dev', 'test', 'support']}

            ]
        "404":
          description: User not found
      summary: Get custom User tags
      tags:
        - user
    post:
      parameters:
        - description: Feedback's User ID
          in: path
          name: id
          required: true
          type: number
        - description: |-
            An array of maps specifying tags under each tag group, for example:

            [

            {'impacts' => ['sales']},

            {'resources' => ['dev', 'test', 'support']}

            ]
          in: body
          name: tags
          required: true
          schema:
            $ref: "#/definitions/Tags"
      responses:
        "200":
          description: Updated User tags
        "404":
          description: User not found
      summary: Overwrite current custom User tags with the given tags
      tags:
        - user
  /vendor_users:
    post:
      consumes:
        - application/json
      description: the POST /vendor_users is very similar to the POST /users/invite_vendor_user but /vendor_users is intended for consumers to refresh team member data periodically, rather than just a one-off user creation.
      parameters:
        - in: body
          name: data
          required: true
          schema:
            properties:
              email:
                type: string
              external_id:
                type: string
              full_name:
                type: string
              permission_group_id:
                format: integer
                type: number
              team:
                description: A comma seperated list of teams the user belongs to
                type: string
            type: object
      responses:
        "200":
          description: success
      summary: Create or update a team member by their external_id
      tags:
        - user
        - team
  /votes:
    get:
      parameters:
        - description: Include only votes by User that voted on a feature.
          in: query
          name: user_id
          required: false
          type: integer
        - description: Include only votes for Feature with this Feature ID
          in: query
          name: feature_id
          required: false
          type: integer
        - description: Include only votes that are positive
          in: query
          name: positive
          required: false
          type: boolean
        - description: Include only votes that are negative
          in: query
          name: negative
          required: false
          type: boolean
        - description: Offset to start at
          in: query
          minimum: 0
          name: offset
          required: false
          type: number
        - description: Limit the number of records returned
          in: query
          minimum: 0
          name: limit
          required: false
          type: number
      responses:
        "200":
          description: Vote records
          schema:
            items:
              $ref: "#/definitions/Vote"
            type: array
      tags:
        - votes
    post:
      description: Automatically subscribes/unsubscribes the User to the specifed feature depending on the quantity value
      parameters:
        - in: body
          name: data
          required: true
          schema:
            properties:
              user_id:
                type: string
              votes:
                items:
                  $ref: "#/definitions/FeatureVote"
                type: array
            type: object
      responses:
        "200":
          description: Updated votes
      summary: update specified votes for a User
      tags:
        - votes
definitions:
  Account:
    properties:
      created_at:
        format: dateTime
        type: string
      external_id:
        description: ID for the Account, provided by the Feedback Customer
        type: string
      id:
        type: string
      is_paying:
        type: boolean
      monthly_value:
        format: float
        type: number
      name:
        type: string
      status:
        type: string
    type: object
  AccountWithTags:
    properties:
      created_at:
        format: dateTime
        type: string
      id:
        type: string
      is_paying:
        type: boolean
      monthly_value:
        format: float
        type: number
      name:
        type: string
      status:
        type: string
      tags:
        $ref: "#/definitions/Tags"
    type: object
  Comment:
    properties:
      created_at:
        format: dateTime
        type: string
      feature_id:
        type: integer
      is_private:
        description: Is this Comment hidden from EndUsers?
        type: boolean
      text:
        type: string
      updated_at:
        format: dateTime
        type: string
      user_id:
        type: integer
    type: object
  EndUserPing:
    properties:
      account:
        $ref: "#/definitions/AccountWithTags"
      return_url:
        type: string
      user:
        properties:
          allowed_products:
            $ref: "#/definitions/Products"
          created_at:
            format: dateTime
            type: string
          email:
            type: string
          full_name:
            type: string
          id:
            type: string
          roles:
            enum:
              - endUser
            type: string
          tags:
            $ref: "#/definitions/Tags"
        type: object
    type: object
  Feature:
    properties:
      app_url:
        description: URL for this Feature
        type: string
      created_at:
        type: string
      created_by_user_id:
        type: integer
      declined_at:
        type: string
      description:
        type: string
      developing_at:
        type: string
      effort:
        description: How much Effort is assigned to the development of this Feature. Not visible to EndUsers
        type: integer
      form_entry:
        description: a JSON serialized version of the Form containing the description and other fields for this Feature.
        type: string
      id:
        type: number
      is_private:
        description: Is this Feature hidden from EndUsers?
        type: boolean
      merged_to_feature_id:
        description: If this Feature was merged into another, the ID of the preserved Feature
        type: integer
      planned_at:
        type: string
      products:
        items:
          description: Products associated with this Feature
          type: string
        type: array
      released_at:
        type: string
      resolution:
        description: The latest Resolution set by the VendorUser
        type: string
      resolved_by_user_id:
        type: integer
      status:
        enum:
          - new
          - waiting
          - planned
          - developing
          - released
          - declined
        type: string
      status_changed_at:
        type: string
      tags:
        $ref: "#/definitions/Tags"
      title:
        type: string
      updated_at:
        type: string
      updated_by_user_id:
        type: integer
      uploads:
        items:
          type: string
        type: array
      vendor_id:
        type: integer
      view_count:
        description: How many times has this Feature been viewed. May only be visible to VendorUsers, depending on config
        type: integer
      waiting_at:
        type: string
    type: object
  FeatureVote:
    properties:
      feature_id:
        type: string
      quantity:
        description: Value between -1 and 1000000. -1 indicates that the User is "Not Interested" in the feature.
        type: integer
    type: object
  Products:
    description: |-
      Supplied as an array of maps where each map describes an existing or new product e.g [{id:exising_product_id, name:existing name}, {id:new_product_id, name: new product name}]. 
      Existing product id/names held in your account can be referenced at https://feedback.pendo.io/app/#/vendor/products
    items:
      type: string
    type: array
  Tags:
    description: |-
      Tags can contain simple tags or categorised tags. Simple tags are supplied as an array of Strings
      Simple Tag Example:
      ['Foo', 'Bar']. 
      To put the tags in categories replace the Strings with maps of using tag category as the key and tag value as the value where value can be array of strings, e.g
      Categorised Tag Example:
      [
      {'Color':['Red', 'Yellow']}, 
      {'Flavor':['Cherry']}
      ] 
      Simple and categorised tags can be mixed in the same array.
      Below validations are done on the tag values of both simple and categorised tags:
      1. Tag values must be strings
      2. Tags must be at least 2 characters in length
      3. Invalid characters (we dont accept following characters in tag value)  , | { } : < > 
  User:
    properties:
      account:
        $ref: "#/definitions/UserAccount"
      created_at:
        format: dateTime
        type: string
      email:
        type: string
      external_id:
        type: string
      id:
        type: string
      name:
        type: string
      roles:
        enum:
          - endUser
        type: string
    type: object
  UserAccount:
    properties:
      id:
        type: string
      monthly_value:
        format: float
        type: number
      name:
        type: string
      status:
        enum:
          - paying
          - prospect
          - not_paying
        type: string
    type: object
  Vote:
    properties:
      created_at:
        type: string
      feature_id:
        type: integer
      quantity:
        description: A negative number indicates that the User has indicated "Not Interested" in a Features. Between 0 and 1000000 is the User's current prioritization of the Feature.
        type: integer
      updated_at:
        type: string
      user_id:
        type: integer
    type: object
