Planable Social Listening API

The Social Listening API from Planable — 7 operation(s). Track brand and topic keywords for a workspace, then read matched mentions, daily metrics, aggregated summaries and sync status.

Operations 7

GET /keywords List tracked keywords
POST /keywords Track a keyword
DELETE /keywords/{keywordId} Stop tracking a keyword
GET /keywords/{keywordId}/mentions List mentions for a tracked keyword
GET /keywords/{keywordId}/metrics/summary Aggregated metrics for a tracked keyword
GET /keywords/{keywordId}/metrics Daily metrics for a tracked keyword
GET /keywords/{keywordId}/sync-status Get keyword sync status

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/planable-social-listening-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

planable-social-listening-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Planable Public Social Listening API
  version: 1.0.0
  description: 'REST API for managing Planable companies, workspaces, pages, posts and more.


    **Plan eligibility:** new API tokens can only be generated by companies on the **Pro** and **Enterprise** plans. Tokens that have already been generated continue to work regardless of plan.'
servers:
- url: https://api.planable.io/api/v1
security:
- bearerAuth: []
tags:
- name: Social Listening
paths:
  /keywords:
    get:
      tags:
      - Social Listening
      summary: List tracked keywords
      description: Lists the keywords tracked for a workspace, optionally filtered by type.
      parameters:
      - name: workspaceId
        in: query
        required: true
        schema:
          type: string
      - name: type
        in: query
        required: false
        schema:
          type: string
          enum:
          - brand
          - topic
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Tracked keywords
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        keywordId:
                          type: string
                        text:
                          type: string
                        type:
                          type: string
                          enum:
                          - brand
                          - topic
                        createdAt:
                          type: string
                          format: date-time
                      required:
                      - keywordId
                      - text
                      - type
                      - createdAt
                required:
                - data
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Token cannot read this workspace
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      tags:
      - Social Listening
      summary: Track a keyword
      description: Starts tracking a keyword for a workspace. Re-adding an already-tracked keyword is idempotent — it returns 200 with the existing row instead of creating a duplicate. The response contains the keyword object only (no sync state); poll `GET /keywords/{keywordId}/sync-status` until the sync completes, same contract as `POST /pages/{id}/sync` → `GET /pages/{id}/sync-status`.
      security:
      - bearerAuth:
        - write
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                workspaceId:
                  type: string
                  minLength: 1
                keyword:
                  type: string
                  minLength: 1
                  maxLength: 200
                type:
                  type: string
                  enum:
                  - brand
                  - topic
                  default: topic
              required:
              - workspaceId
              - keyword
      responses:
        '200':
          description: Keyword was already tracked (idempotent re-add)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      keywordId:
                        type: string
                      text:
                        type: string
                      type:
                        type: string
                        enum:
                        - brand
                        - topic
                      createdAt:
                        type: string
                        format: date-time
                    required:
                    - keywordId
                    - text
                    - type
                    - createdAt
                required:
                - data
        '201':
          description: Keyword is now tracked
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      keywordId:
                        type: string
                      text:
                        type: string
                      type:
                        type: string
                        enum:
                        - brand
                        - topic
                      createdAt:
                        type: string
                        format: date-time
                    required:
                    - keywordId
                    - text
                    - type
                    - createdAt
                required:
                - data
        '400':
          description: Keyword limit reached, brand limit reached, or type conflict with an existing listener
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Token lacks the write scope, workspace is outside token scope, or workspace is a sample workspace
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /keywords/{keywordId}:
    delete:
      tags:
      - Social Listening
      summary: Stop tracking a keyword
      description: Stops tracking a keyword on a workspace. Returns 204 when the listener is removed.
      security:
      - bearerAuth:
        - write
      parameters:
      - name: keywordId
        in: path
        required: true
        schema:
          type: string
      - name: workspaceId
        in: query
        required: true
        schema:
          type: string
      responses:
        '204':
          description: Keyword untracked
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Token lacks the write scope, workspace is outside token scope, or workspace is a sample workspace
        '404':
          description: Keyword is not tracked by this workspace
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /keywords/{keywordId}/mentions:
    get:
      tags:
      - Social Listening
      summary: List mentions for a tracked keyword
      description: Windowed mentions for a keyword, with optional platform/sentiment filter and sort. Brand listeners only return brand mentions. Mentions are returned as a curated, typed shape — common fields plus per-platform metric fields as optional properties.
      parameters:
      - name: keywordId
        in: path
        required: true
        schema:
          type: string
      - name: workspaceId
        in: query
        required: true
        schema:
          type: string
      - name: range
        in: query
        required: false
        schema:
          type: string
          enum:
          - 7d
          - 14d
          - 30d
          default: 7d
      - name: startDate
        in: query
        required: false
        schema:
          type: string
          format: date-time
      - name: endDate
        in: query
        required: false
        schema:
          type: string
          format: date-time
      - name: platform
        in: query
        required: false
        schema:
          type: string
          enum:
          - twitter
          - youtube
          - reddit
          - tiktok
          - facebook
          - instagram
      - name: sentiment
        in: query
        required: false
        schema:
          type: string
          enum:
          - all
          - positive
          - negative
          - neutral
          default: all
      - name: sortBy
        in: query
        required: false
        schema:
          type: string
          enum:
          - engagement
          - recency
          default: engagement
      - name: cursor
        in: query
        required: false
        schema:
          type: integer
          minimum: 0
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Mentions for the keyword
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        platform:
                          type: string
                        publishedAt:
                          type: string
                          format: date-time
                        engagement:
                          type: number
                        sentiment:
                          type: string
                          enum:
                          - positive
                          - negative
                          - neutral
                        url:
                          type: string
                        text:
                          type: string
                        author:
                          type: object
                          properties:
                            name:
                              type: string
                            username:
                              type:
                              - string
                              - 'null'
                            profileImageUrl:
                              type:
                              - string
                              - 'null'
                          required:
                          - name
                          - username
                          - profileImageUrl
                        likes:
                          type: number
                        comments:
                          type: number
                        shares:
                          type: number
                        views:
                          type: number
                        upvotes:
                          type: number
                        replies:
                          type: number
                        retweets:
                          type: number
                        quotes:
                          type: number
                        bookmarks:
                          type: number
                        impressions:
                          type: number
                        plays:
                          type: number
                        saves:
                          type: number
                      required:
                      - platform
                      - publishedAt
                      - engagement
                      - url
                      - text
                      - author
                  pagination:
                    type: object
                    properties:
                      nextCursor:
                        type:
                        - number
                        - 'null'
                      total:
                        type: number
                    required:
                    - nextCursor
                    - total
                required:
                - data
                - pagination
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Token cannot read this workspace
        '404':
          description: Keyword is not tracked by this workspace
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /keywords/{keywordId}/metrics/summary:
    get:
      tags:
      - Social Listening
      summary: Aggregated metrics for a tracked keyword
      description: Aggregated mention, engagement, sentiment, and per-platform totals for a keyword over a window. Internal API-spend fields are never exposed.
      parameters:
      - name: keywordId
        in: path
        required: true
        schema:
          type: string
      - name: workspaceId
        in: query
        required: true
        schema:
          type: string
      - name: range
        in: query
        required: false
        schema:
          type: string
          enum:
          - 7d
          - 14d
          - 30d
          default: 7d
      - name: startDate
        in: query
        required: false
        schema:
          type: string
          format: date-time
      - name: endDate
        in: query
        required: false
        schema:
          type: string
          format: date-time
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Aggregated metrics summary
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      mentions:
                        type: number
                      engagement:
                        type: number
                      sentiment:
                        type: object
                        properties:
                          positive:
                            type: number
                          negative:
                            type: number
                          neutral:
                            type: number
                        required:
                        - positive
                        - negative
                        - neutral
                      platformBreakdown:
                        type: object
                        additionalProperties:
                          type: object
                          properties:
                            mentions:
                              type: number
                            engagement:
                              type: number
                          required:
                          - mentions
                          - engagement
                      daysWithData:
                        type: number
                    required:
                    - mentions
                    - engagement
                    - sentiment
                    - platformBreakdown
                    - daysWithData
                required:
                - data
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Token cannot read this workspace
        '404':
          description: Keyword is not tracked by this workspace
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /keywords/{keywordId}/metrics:
    get:
      tags:
      - Social Listening
      summary: Daily metrics for a tracked keyword
      description: Daily mention, engagement, sentiment, and per-platform breakdown for a keyword over a window. Internal API-spend fields (costs/totalCost) are never exposed.
      parameters:
      - name: keywordId
        in: path
        required: true
        schema:
          type: string
      - name: workspaceId
        in: query
        required: true
        schema:
          type: string
      - name: range
        in: query
        required: false
        schema:
          type: string
          enum:
          - 7d
          - 14d
          - 30d
          default: 7d
      - name: startDate
        in: query
        required: false
        schema:
          type: string
          format: date-time
      - name: endDate
        in: query
        required: false
        schema:
          type: string
          format: date-time
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Daily metrics series
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        date:
                          type: string
                          format: date-time
                        mentions:
                          type: number
                        engagement:
                          type: number
                        sentiment:
                          type: object
                          properties:
                            positive:
                              type: number
                            negative:
                              type: number
                            neutral:
                              type: number
                          required:
                          - positive
                          - negative
                          - neutral
                        platformBreakdown:
                          type: object
                          additionalProperties:
                            type: object
                            properties:
                              mentions:
                                type: number
                              engagement:
                                type: number
                            required:
                            - mentions
                            - engagement
                      required:
                      - date
                      - mentions
                      - engagement
                      - platformBreakdown
                required:
                - data
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Token cannot read this workspace
        '404':
          description: Keyword is not tracked by this workspace
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /keywords/{keywordId}/sync-status:
    get:
      tags:
      - Social Listening
      summary: Get keyword sync status
      description: Polls the sync job status for a tracked keyword. After `POST /keywords`, poll this endpoint until `status` is `complete` (or `removed` if the keyword was deleted mid-poll). Mirrors `GET /pages/{id}/sync-status`.
      parameters:
      - name: keywordId
        in: path
        required: true
        schema:
          type: string
      - name: workspaceId
        in: query
        required: true
        schema:
          type: string
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Keyword sync status
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      keywordId:
                        type: string
                      status:
                        type: string
                        enum:
                        - running
                        - complete
                        - removed
                      totalJobs:
                        type: integer
                        minimum: 0
                      completedJobs:
                        type: integer
                        minimum: 0
                    required:
                    - keywordId
                    - status
                    - totalJobs
                    - completedJobs
                required:
                - data
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Token cannot read this workspace
        '404':
          description: Keyword has a listener but no sync jobs were found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
              - VALIDATION_ERROR
              - UNAUTHORIZED
              - FORBIDDEN
              - NOT_FOUND
              - METHOD_NOT_ALLOWED
              - RATE_LIMITED
              - POST_ALREADY_PUBLISHED
              - PUBLISHING_IN_PROGRESS
              - WORKSPACE_LIMIT_REACHED
              - INTERNAL
            message:
              type: string
            requestId:
              type: string
          required:
          - code
          - message
          - requestId
      required:
      - error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: pln_*