postlake-dev Discovery API

The Discovery API from postlake-dev — 5 operation(s) for discovery.

Operations 5

GET /v1/discover/posts Search public posts #
GET /v1/discover/profiles/{handle} Look someone up #
GET /v1/discover/profiles/{handle}/posts Someone else's public posts #
GET /v1/discover/creators Find creators to work with #
GET /v1/discover/places Find a place to tag on a post #

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/postlake-dev:postlake-dev-discovery-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

postlake-dev-discovery-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: PostLake Discovery API
  version: 1.0.0
  description: Unified social media API. One API key, 10 platforms, normalised responses. Built for agents and developers.
  contact:
    url: https://postlake.dev
servers:
- url: https://api.postlake.dev
security:
- bearerAuth: []
tags:
- name: Discovery
paths:
  /v1/discover/posts:
    get:
      tags:
      - Discovery
      summary: Search public posts
      description: 'Search the network itself rather than your own posts, so an agent can see what is already being said before it writes. Runs on every connected network that supports searching; the ones that cannot are named in `problems`. Two limits decide whether a result means anything on Instagram, and neither is a rate limit you can retry past. Instagram has NO keyword search: a multi-word query cannot match a hashtag and comes back as a `problems` entry rather than an empty list. And Meta caps this at 30 UNIQUE hashtags per account per 7 days, so a scouting run has a weekly budget. `sort=recent` reads Meta''s recent_media edge, which only covers the last 24 hours, so an empty recent result means nothing was posted today rather than that the tag is unused. Instagram results also carry `authorHidden: true` and can never name their author: Meta strips personally identifiable information from them, so post search cannot be used to find someone to contact.'
      parameters:
      - name: q
        in: query
        required: true
        schema:
          type: string
        description: What to search for
      - name: mode
        in: query
        required: false
        schema:
          type: string
          enum:
          - keyword
          - tag
        description: Search the words (default) or a topic tag
      - name: sort
        in: query
        required: false
        schema:
          type: string
          enum:
          - top
          - recent
        description: Best match (default) or newest first
      - name: mediaType
        in: query
        required: false
        schema:
          type: string
          enum:
          - text
          - image
          - video
      - name: author
        in: query
        required: false
        schema:
          type: string
        description: Only this handle's posts
      - name: since
        in: query
        required: false
        schema:
          type: string
          format: date-time
      - name: until
        in: query
        required: false
        schema:
          type: string
          format: date-time
      - name: account
        in: query
        required: false
        schema:
          type: string
        description: Search one connection only. Omit to search them all.
      - name: cursor
        in: query
        required: false
        schema:
          type: string
      - name: limit
        in: query
        required: false
        schema:
          type: integer
        description: 1-100
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/DiscoveredPost'
                  cursor:
                    type: string
                    nullable: true
                    description: Opaque. Pass it back verbatim; null means the end.
                  problems:
                    type: array
                    items:
                      $ref: '#/components/schemas/ReadProblem'
      operationId: getV1DiscoverPosts
      x-operation-id-source: derived
  /v1/discover/profiles/{handle}:
    get:
      tags:
      - Discovery
      summary: Look someone up
      description: 'One network only: the same handle on two networks is usually two different people, so merging them would invent someone who does not exist. Counts are null where the network does not publish them, which is not the same as zero.'
      parameters:
      - name: handle
        in: path
        required: true
        schema:
          type: string
        description: With or without the @
      - name: account
        in: query
        required: true
        schema:
          type: string
        description: Which connection to look on
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicProfile'
      operationId: getV1DiscoverProfilesByHandle
      x-operation-id-source: derived
  /v1/discover/profiles/{handle}/posts:
    get:
      tags:
      - Discovery
      summary: Someone else's public posts
      parameters:
      - name: handle
        in: path
        required: true
        schema:
          type: string
      - name: account
        in: query
        required: true
        schema:
          type: string
      - name: cursor
        in: query
        required: false
        schema:
          type: string
      - name: limit
        in: query
        required: false
        schema:
          type: integer
        description: 1-100
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/DiscoveredPost'
                  cursor:
                    type: string
                    nullable: true
                  problems:
                    type: array
                    items:
                      $ref: '#/components/schemas/ReadProblem'
      operationId: getV1DiscoverProfilesByHandlePosts
      x-operation-id-source: derived
  /v1/discover/creators:
    get:
      tags:
      - Discovery
      summary: Find creators to work with
      description: 'Search Meta creator discovery for people a brand could partner with. A Facebook Page searches Facebook Creator Discovery directly. An Instagram account connected through Facebook searches Instagram Creator Marketplace. Entries marked `sample: true` are test data, not real outreach targets.'
      parameters:
      - name: account
        in: query
        required: true
        schema:
          type: string
        description: A Facebook Page for Facebook Creator Discovery, or an Instagram account connected through Facebook for Instagram Creator Marketplace.
      - name: q
        in: query
        required: false
        schema:
          type: string
        description: Free-text search.
      - name: countries
        in: query
        required: false
        schema:
          type: string
        description: Comma-separated country codes.
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 50
      - name: cursor
        in: query
        required: false
        schema:
          type: string
      responses:
        '200':
          description: Creators
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        handle:
                          type: string
                        displayName:
                          type: string
                          nullable: true
                        avatarUrl:
                          type: string
                          nullable: true
                        bio:
                          type: string
                          nullable: true
                        categories:
                          type: array
                          items:
                            type: string
                        country:
                          type: string
                          nullable: true
                        portfolioUrl:
                          type: string
                          nullable: true
                          format: uri
                          description: Individual creator profile URL. Null for Meta test results.
                        platforms:
                          type: array
                          items:
                            type: string
                        verified:
                          type: boolean
                          nullable: true
                        hasBrandPartnershipExperience:
                          type: boolean
                          nullable: true
                        followsBrand:
                          type: boolean
                          nullable: true
                        sample:
                          type: boolean
                          description: True until PostLake has Meta Advanced Access configured. Never use a sample result for outreach.
                      required:
                      - id
                      - handle
                      - sample
                  cursor:
                    type: string
                    nullable: true
                  platform:
                    $ref: '#/components/schemas/Platform'
                required:
                - items
                - cursor
                - platform
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          description: The network refused, and retrying will not help. A brand that has not accepted the relevant Meta creator-product terms answers `creator_marketplace_not_onboarded`. `retryable` is false and `fix` carries the exact Facebook or Instagram click path. Check `discovers.creators` and `blocked` on GET /v1/social-accounts/{id} first and you can avoid this call entirely.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      operationId: getV1DiscoverCreators
      x-operation-id-source: derived
  /v1/discover/places:
    get:
      tags:
      - Discovery
      summary: Find a place to tag on a post
      description: Pass a name, or a latitude and longitude together. The id returned goes in the post's `locationId` option, and only works on the network it came from.
      parameters:
      - name: account
        in: query
        required: true
        schema:
          type: string
      - name: q
        in: query
        required: false
        schema:
          type: string
      - name: latitude
        in: query
        required: false
        schema:
          type: number
        description: Use with longitude
      - name: longitude
        in: query
        required: false
        schema:
          type: number
        description: Use with latitude
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Place'
                  platform:
                    type: string
      operationId: getV1DiscoverPlaces
      x-operation-id-source: derived
components:
  schemas:
    ReadProblem:
      type: object
      description: A network that could not be read for this request. Its presence is what lets you tell 'nothing happened' from 'we could not look'.
      properties:
        account:
          type: string
        platform:
          type: string
        reason:
          type: string
    PublicProfile:
      type: object
      description: Someone else's public profile.
      properties:
        platform:
          type: string
        handle:
          type: string
        displayName:
          type: string
          nullable: true
        avatarUrl:
          type: string
          nullable: true
        bio:
          type: string
          nullable: true
        verified:
          type: boolean
        followerCount:
          type: integer
          nullable: true
          description: null where the network does not publish it, which is not the same as zero.
        recent:
          type: object
          nullable: true
          description: The last 7 days, where the network reports it. Each figure is null when unpublished, never 0.
          properties:
            likes:
              type: integer
              nullable: true
            quotes:
              type: integer
              nullable: true
            reposts:
              type: integer
              nullable: true
            views:
              type: integer
              nullable: true
        id:
          type: string
          nullable: true
    Place:
      type: object
      description: A place that can be tagged on a post. Ids are per-network and only mean anything to the network they came from, so the platform travels with them.
      properties:
        id:
          type: string
        platform:
          type: string
        name:
          type: string
        address:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        latitude:
          type: number
          nullable: true
        longitude:
          type: number
          nullable: true
    ErrorResponse:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/NormalisedError'
      required:
      - error
    NormalisedError:
      type: object
      description: '`type` is the coarse category you route on and is deliberately small, so it cannot say WHICH input was wrong. `code`, `fix`, `docs` and `param` are what turn a rejection into something a caller can act on rather than guess at. They are optional only in the sense that not every error has all four.'
      properties:
        type:
          type: string
          description: Coarse category to route on, e.g. rate_limited, auth_expired, platform_rejected.
        message:
          type: string
        platform:
          oneOf:
          - $ref: '#/components/schemas/Platform'
          - type: 'null'
        retryable:
          type: boolean
        code:
          type: string
          description: Stable, granular handle to branch on, e.g. text_too_long. Also the anchor in the error reference.
        fix:
          type: string
          description: The next action, in plain words. Safe to show a person as-is.
        docs:
          type: string
          format: uri
          description: Where the rule is written down, so it is learned once rather than rediscovered.
        param:
          type: string
          description: The request field at fault, so a form can mark the right input.
      required:
      - type
      - message
      - retryable
    SocialActor:
      type: object
      properties:
        handle:
          type: string
        displayName:
          type: string
          nullable: true
        avatarUrl:
          type: string
          nullable: true
        id:
          type: string
          nullable: true
          description: The network's own id, for follow/block/mute
    Platform:
      type: string
      enum:
      - bluesky
      - threads
      - x
      - linkedin
      - instagram
      - tiktok
      - facebook
      - youtube
      - pinterest
    DiscoveredPost:
      type: object
      description: 'A post found by searching or browsing, rather than one you published. Deliberately not the Post shape: far less is known about someone else''s post, and a shape full of nulls invites you to assume they are readable.'
      properties:
        id:
          type: string
        platform:
          type: string
        author:
          $ref: '#/components/schemas/SocialActor'
        text:
          type: string
        createdAt:
          type: string
          format: date-time
        url:
          type: string
          nullable: true
        mediaType:
          type: string
          enum:
          - text
          - image
          - video
          - other
          description: '''other'' keeps a new network media type from breaking a parser that switches on this.'
        isReply:
          type: boolean
        isQuote:
          type: boolean
        authorHidden:
          type: boolean
          description: 'True when the network REFUSES to name the author, as opposed to us failing to read it. Instagram hashtag results are the case: Meta rejects the username field on media returned by a tag search, so author.handle is necessarily empty. Treat an empty handle WITHOUT this flag as a bug; with it, as the network''s rule.'
  responses:
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: unauthorized
              message: missing or invalid api key
              retryable: false