Pollfish Survey Distribution and Offerwall API

The SDK-alternative survey-serving surface. Register a device to request a matching survey (or a JSON offerwall list of surveys with reward and remaining-completes data), then load the returned survey_link to render the survey to the respondent. Supports single-survey, HTML offerwall, and JSON offerwall modes, targeting via demographic and device parameters, and reward conversion signing. Note the host is wss.pollfish.com but the transport is HTTPS GET, not WebSocket.

OpenAPI Specification

pollfish-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Pollfish API
  version: '2026.07'
  description: >-
    Unified OpenAPI description of Pollfish's documented public REST surfaces.
    Pollfish is a mobile survey and market-research platform owned by Prodege LLC.


    Two hosts are covered:

    - `https://www.pollfish.com` - the Dashboard API (publisher app management and
      analytics), HTTP Basic Auth with your Pollfish account email and secret key.
    - `https://wss.pollfish.com` - the survey-serving / offerwall API used as an
      alternative to the SDK. Despite the `wss` hostname, the transport is HTTPS
      GET/HEAD, NOT WebSocket.


    Endpoints are annotated with `x-endpoint-status` of `confirmed` (documented in
    Pollfish's own GitHub docs at github.com/pollfish/docs) or `modeled` (shape
    inferred where the response body is HTML or the schema is not exhaustively
    documented). Survey creation / audience design for researchers is done in the
    Pollfish dashboard and is not part of this documented public REST API.
  contact:
    name: Pollfish (Prodege)
    url: https://www.pollfish.com/docs
  termsOfService: https://www.pollfish.com/terms/
  license:
    name: Proprietary
    url: https://www.pollfish.com/terms/
servers:
  - url: https://www.pollfish.com
    description: Dashboard API (apps, performance, revenue, demographics, logs)
  - url: https://wss.pollfish.com
    description: Survey serving and offerwall API (HTTPS, not WebSocket)
tags:
  - name: Apps
    description: Publisher app / placement management (Dashboard API).
  - name: Performance
    description: Survey-serving performance metrics.
  - name: Revenue
    description: Revenue reporting per provider and per country.
  - name: Demographics
    description: Respondent demographic profiles.
  - name: Logs
    description: Per-user survey logs and disqualification reasons.
  - name: Survey Distribution
    description: Device register, offerwall, and survey rendering.
paths:
  /api/public/v2/apps:
    get:
      operationId: listApps
      tags: [Apps]
      summary: List apps
      description: Returns an array of the authenticated developer's apps.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      responses:
        '200':
          description: Array of app objects.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/App'
    post:
      operationId: createApp
      tags: [Apps]
      summary: Create an app
      description: Creates a new publisher app (monetization placement) and returns its api_key.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppCreate'
      responses:
        '200':
          description: The created app.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/App'
        '400':
          description: Missing or invalid parameters.
  /api/public/v2/apps/{api_key}:
    parameters:
      - $ref: '#/components/parameters/ApiKeyPath'
    get:
      operationId: getApp
      tags: [Apps]
      summary: Get an app
      description: Returns a single app object by its api_key.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      responses:
        '200':
          description: The app object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/App'
        '403':
          description: App does not exist or you lack permission.
    put:
      operationId: updateApp
      tags: [Apps]
      summary: Update an app
      description: Updates properties of an existing app. Only supplied fields are changed.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppUpdate'
      responses:
        '200':
          description: The updated app.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/App'
        '400':
          description: Missing or invalid parameters.
        '403':
          description: App does not exist or you lack permission.
    delete:
      operationId: deleteApp
      tags: [Apps]
      summary: Delete an app
      description: Deletes an app by its api_key.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      responses:
        '204':
          description: App deleted.
        '403':
          description: App does not exist or you lack permission.
  /api/public/v3/apps/performance:
    get:
      operationId: getAllAppsPerformance
      tags: [Performance]
      summary: Performance for all apps
      description: >-
        Returns performance metrics (served, seen, accepted, completed) per survey
        network for all of the developer's apps over a date range of up to 31 days.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/From'
        - $ref: '#/components/parameters/To'
      responses:
        '200':
          description: Performance series grouped by network.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NetworkPerformance'
        '400':
          description: Missing or invalid parameters.
  /api/public/v3/apps/{api_key}/performance:
    parameters:
      - $ref: '#/components/parameters/ApiKeyPath'
    get:
      operationId: getAppPerformance
      tags: [Performance]
      summary: Performance for one app
      description: Returns performance metrics for a single app over a date range of up to 31 days.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/From'
        - $ref: '#/components/parameters/To'
      responses:
        '200':
          description: Performance series grouped by network.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NetworkPerformance'
        '400':
          description: Missing or invalid parameters.
  /api/public/v3/apps/{api_key}/performanceByCountry:
    parameters:
      - $ref: '#/components/parameters/ApiKeyPath'
    get:
      operationId: getAppPerformanceByCountry
      tags: [Performance]
      summary: Performance for one app grouped by country
      description: Returns performance metrics for a single app, grouped by country and network, over a date range of up to 31 days.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/From'
        - $ref: '#/components/parameters/To'
      responses:
        '200':
          description: Country-grouped performance. Shape is documented by example; modeled loosely here.
          x-endpoint-status: modeled
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    countryISO:
                      type: string
                    data:
                      type: array
                      items:
                        $ref: '#/components/schemas/NetworkPerformance'
        '400':
          description: Missing or invalid parameters.
  /api/public/v3/apps/revenue:
    get:
      operationId: getAllAppsRevenue
      tags: [Revenue]
      summary: Revenue per provider for all apps
      description: Returns total revenue per survey provider for all apps over a date range, optionally filtered by country.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/From'
        - $ref: '#/components/parameters/To'
        - $ref: '#/components/parameters/Countries'
      responses:
        '200':
          description: Revenue series grouped by provider.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProviderRevenue'
        '400':
          description: Missing or invalid parameters.
  /api/public/v3/apps/{api_key}/revenue:
    parameters:
      - $ref: '#/components/parameters/ApiKeyPath'
    get:
      operationId: getAppRevenue
      tags: [Revenue]
      summary: Revenue per provider for one app
      description: Returns total revenue per survey provider for a single app over a date range, optionally filtered by country.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/From'
        - $ref: '#/components/parameters/To'
        - $ref: '#/components/parameters/Countries'
      responses:
        '200':
          description: Revenue series grouped by provider.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProviderRevenue'
        '400':
          description: Missing or invalid parameters.
  /api/public/v3/apps/revenuePerCountry:
    get:
      operationId: getAllAppsRevenuePerCountry
      tags: [Revenue]
      summary: Revenue per country for all apps
      description: Returns total revenue per country for all apps over a date range, optionally filtered by country.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/From'
        - $ref: '#/components/parameters/To'
        - $ref: '#/components/parameters/Countries'
      responses:
        '200':
          description: Daily revenue with per-country breakdown.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RevenuePerCountryDay'
        '400':
          description: Missing or invalid parameters.
  /api/public/v3/apps/{api_key}/revenuePerCountry:
    parameters:
      - $ref: '#/components/parameters/ApiKeyPath'
    get:
      operationId: getAppRevenuePerCountry
      tags: [Revenue]
      summary: Revenue per country for one app
      description: Returns total revenue per country for a single app over a date range, optionally filtered by country.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/From'
        - $ref: '#/components/parameters/To'
        - $ref: '#/components/parameters/Countries'
      responses:
        '200':
          description: Daily revenue with per-country breakdown.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RevenuePerCountryDay'
        '400':
          description: Missing or invalid parameters.
  /api/public/v3/apps/demographics:
    get:
      operationId: getRespondentDemographics
      tags: [Demographics]
      summary: Get respondent demographics
      description: Returns the collected demographic profile for a given respondent device id.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - name: user
          in: query
          required: true
          description: The device id to fetch demographics for.
          schema:
            type: string
      responses:
        '200':
          description: Demographic profile using Pollfish enumeration codes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Demographics'
        '400':
          description: Missing or invalid parameters.
  /api/public/v3/apps/{api_key}/users_log:
    parameters:
      - $ref: '#/components/parameters/ApiKeyPath'
    get:
      operationId: getUsersLog
      tags: [Logs]
      summary: Get user logs
      description: Returns paginated per-user survey logs for a given device_id or request_uuid.
      x-endpoint-status: confirmed
      security:
        - basicAuth: []
      parameters:
        - name: key
          in: query
          required: true
          description: The search term (device_id or request_uuid).
          schema:
            type: string
        - name: page
          in: query
          required: false
          description: Page number when results are paginated.
          schema:
            type: integer
        - name: rows
          in: query
          required: false
          description: Number of rows returned.
          schema:
            type: integer
      responses:
        '200':
          description: Paginated survey log results.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UsersLog'
        '400':
          description: Missing or invalid parameters.
  /v2/device/register/true:
    get:
      operationId: registerDevice
      tags: [Survey Distribution]
      summary: Request a survey / offerwall for a device
      description: >-
        Requests a matching survey (or, with `offerwall=true`, an offerwall) for a
        respondent device. All register parameters are passed inside the `json`
        query parameter as a JSON string; `dontencrypt=true` must be included. With
        `offerwall=true` and `content_type=json`, returns a JSON list of surveys
        with reward and remaining-completes data; otherwise returns an HTML page.
        Response is HTTP 200 when a survey is available, 204 when none is available.
        This host is wss.pollfish.com but the call is a normal HTTPS GET, not a
        WebSocket connection.
      servers:
        - url: https://wss.pollfish.com
      x-endpoint-status: confirmed
      parameters:
        - name: json
          in: query
          required: true
          description: >-
            URL-encoded JSON object carrying all register parameters (api_key,
            device_id, timestamp, ip, os, locale, version, encryption, placement_key,
            offerwall, content_type, reward_name, reward_conversion, click_id,
            targeting demographics, etc.). See the register JSON schema.
          schema:
            $ref: '#/components/schemas/RegisterJson'
        - name: dontencrypt
          in: query
          required: true
          description: Must be set to true on every request.
          schema:
            type: boolean
            default: true
        - name: sig
          in: query
          required: false
          description: >-
            Base64 + percent-encoded HMAC-SHA1 of reward_conversion+reward_name+click_id
            signed with your account secret key. Required when reward_conversion is passed.
          schema:
            type: string
      responses:
        '200':
          description: >-
            Survey available. Body is an HTML page, or (offerwall JSON mode) an
            OfferwallResponse JSON object.
          content:
            text/html:
              schema:
                type: string
            application/json:
              schema:
                $ref: '#/components/schemas/OfferwallResponse'
        '204':
          description: No survey available.
        '400':
          description: Bad request (for example, "Hash check failed" when sig validation fails).
    head:
      operationId: checkSurveyAvailability
      tags: [Survey Distribution]
      summary: Check survey availability (no body)
      description: Same as the GET register call but returns only the status code, letting you check availability without transferring the HTML body.
      servers:
        - url: https://wss.pollfish.com
      x-endpoint-status: confirmed
      parameters:
        - name: json
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/RegisterJson'
        - name: dontencrypt
          in: query
          required: true
          schema:
            type: boolean
            default: true
      responses:
        '200':
          description: Survey available.
        '204':
          description: No survey available.
  /v2/device/survey/{survey_id}:
    get:
      operationId: loadSurvey
      tags: [Survey Distribution]
      summary: Load / render a specific survey
      description: >-
        Loads a specific survey by id, as referenced by the `survey_link` returned
        in an offerwall response. Renders the survey HTML to the respondent. The
        `json` and `dontencrypt` query parameters mirror the register call. Marked
        modeled because the response is an HTML survey experience rather than a
        documented JSON schema.
      servers:
        - url: https://wss.pollfish.com
      x-endpoint-status: modeled
      parameters:
        - name: survey_id
          in: path
          required: true
          description: The survey id (as returned in an offerwall survey_link).
          schema:
            type: integer
        - name: json
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/RegisterJson'
        - name: dontencrypt
          in: query
          required: true
          schema:
            type: boolean
            default: true
      responses:
        '200':
          description: HTML survey page.
          content:
            text/html:
              schema:
                type: string
        '204':
          description: Survey no longer available.
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: >-
        HTTP Basic Auth for the Dashboard API. Username is your Pollfish account
        email, password is your account secret key (from Account Information in the
        publisher dashboard).
  parameters:
    ApiKeyPath:
      name: api_key
      in: path
      required: true
      description: The app's api_key.
      schema:
        type: string
    From:
      name: from
      in: query
      required: false
      description: Start date (ISO 8601 yyyy-MM-dd, UTC). Defaults to one month before `to`. The from/to window must not exceed 31 days.
      schema:
        type: string
        format: date
    To:
      name: to
      in: query
      required: false
      description: End date (ISO 8601 yyyy-MM-dd, UTC). Defaults to the current date.
      schema:
        type: string
        format: date
    Countries:
      name: countries
      in: query
      required: false
      description: Comma-separated ISO Alpha-2 country codes to filter revenue by. Omit for all countries.
      schema:
        type: string
  schemas:
    App:
      type: object
      properties:
        api_key:
          type: string
        id:
          type: integer
        name:
          type: string
        platform:
          type: string
          description: Android, iOS, Windows Phone, or Web.
        category:
          type: string
          description: IAB category code.
        subcategory:
          type: string
        url:
          type: string
        image:
          type: string
        behavior:
          type: integer
        incentive:
          type: boolean
        revenue:
          type: number
          format: float
        short_surveys_enabled:
          type: boolean
        third_party_surveys_enabled:
          type: boolean
        data_collection_surveys_enabled:
          type: boolean
        rewarded_survey:
          $ref: '#/components/schemas/RewardedSurvey'
        offerwall:
          $ref: '#/components/schemas/OfferwallReward'
    AppCreate:
      type: object
      required: [name, category, subcategory, url, platform]
      properties:
        name:
          type: string
        category:
          type: string
        subcategory:
          type: string
        url:
          type: string
        platform:
          type: integer
          description: 0 android, 1 ios, 2 windows phone, 3 web.
        callback_url:
          type: string
          description: URL for server-to-server postback callbacks.
        behavior:
          type: integer
          description: 0 indicators, 1 dynamic (recommended), 2 force slide regularly, 3 force all the time.
        data_collection_surveys_enabled:
          type: boolean
        third_party_surveys_enabled:
          type: boolean
        rewarded_survey:
          $ref: '#/components/schemas/RewardedSurvey'
        offerwall:
          $ref: '#/components/schemas/OfferwallReward'
    AppUpdate:
      type: object
      properties:
        name:
          type: string
        category:
          type: string
        subcategory:
          type: string
        url:
          type: string
        callback_url:
          type: string
        behavior:
          type: integer
        data_collection_surveys_enabled:
          type: boolean
        third_party_surveys_enabled:
          type: boolean
        rewarded_survey:
          $ref: '#/components/schemas/RewardedSurvey'
        offerwall:
          $ref: '#/components/schemas/OfferwallReward'
    RewardedSurvey:
      type: object
      properties:
        currency_name:
          type: string
        variable_amount:
          type: number
          format: float
        fixed_amount:
          type: boolean
    OfferwallReward:
      type: object
      properties:
        currency_name:
          type: string
        variable_amount:
          type: number
          format: float
    NetworkPerformance:
      type: object
      properties:
        name:
          type: string
          description: Survey network name (Pollfish, Cint, Toluna, etc.).
        data:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
              served:
                type: integer
              seen:
                type: integer
              accepted:
                type: integer
              completed:
                type: integer
    ProviderRevenue:
      type: object
      properties:
        name:
          type: string
        total:
          type: number
          format: float
        data:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
              amount:
                type: number
                format: float
    RevenuePerCountryDay:
      type: object
      properties:
        date:
          type: string
          format: date
        total:
          type: number
          format: float
        countries:
          type: array
          items:
            type: object
            properties:
              iso_code:
                type: string
              amount:
                type: number
                format: float
    Demographics:
      type: object
      description: Demographic enumeration codes; see pollfish.com/docs/demographic-surveys.
      properties:
        device_id:
          type: string
        gender:
          type: integer
        year_of_birth:
          type: integer
        marital_status:
          type: integer
        parental:
          type: integer
        education:
          type: integer
        employment:
          type: integer
        career:
          type: integer
        race:
          type: integer
        income:
          type: integer
    UsersLog:
      type: object
      properties:
        totalCount:
          type: integer
        results:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              survey_started:
                type: integer
                format: int64
                description: Epoch millis when the survey started.
              completed:
                type: boolean
              disqualified_reason:
                type: string
                nullable: true
                description: One of the public termination reasons (Quota Full, Survey Closed, Screenout, Duplicate, VPN, Quality, etc.) or null.
    RegisterJson:
      type: object
      description: >-
        The JSON object passed (URL-encoded) as the `json` query parameter on the
        register/survey calls. Only the most common fields are listed; see the
        Pollfish API documentation for the full parameter table. Every value must
        be a string.
      required: [api_key, device_id, timestamp, ip, os, locale, encryption, version]
      properties:
        api_key:
          type: string
        device_id:
          type: string
          description: Advertising id (IDFA / AAID) or a stable per-user UUID.
        timestamp:
          type: string
          description: Request time in epoch millis.
        ip:
          type: string
        os:
          type: integer
          description: 0 Android, 1 iOS, 2 Windows Phone, 3 Web.
        locale:
          type: string
        encryption:
          type: string
          enum: [NONE]
        version:
          type: integer
          description: Current API version (7).
        placement_key:
          type: string
          description: Placement id whose settings apply.
        offerwall:
          type: boolean
        content_type:
          type: string
          enum: [json, html]
        always_return_content:
          type: boolean
        reward_name:
          type: string
        reward_conversion:
          type: string
        click_id:
          type: string
        debug:
          type: boolean
        sortBy:
          type: string
          enum: [reward, loi, ir]
        order:
          type: string
          enum: [asc, desc]
    OfferwallResponse:
      type: object
      properties:
        surveys:
          type: array
          items:
            $ref: '#/components/schemas/OfferwallSurvey'
        hasDemographics:
          type: boolean
    OfferwallSurvey:
      type: object
      properties:
        survey_id:
          type: integer
        survey_cpa:
          type: integer
          description: Payout in US dollar cents.
        survey_class:
          type: string
          description: Provider and optional type, e.g. "Pollfish/Demographics", "Toluna", "Cint".
        survey_ir:
          type: integer
          description: Estimated incidence rate 0-100.
        survey_loi:
          type: integer
          description: Estimated length of interview in minutes.
        survey_lang:
          type: string
        reward_name:
          type: string
        reward_value:
          type: number
        survey_link:
          type: string
          description: URL to load/render this survey (GET /v2/device/survey/{survey_id}).
        remaining_completes:
          type: integer
          description: Remaining completes (Pollfish surveys only).
        ordering:
          type: integer