Meet the new Scripe, live on October 7.Register

OpenAPI reference · Analytics

Search viral posts (inspiration)

GET/viral-posts

Semantic search over the inspiration feed for high-performing LinkedIn posts relevant to a topic. Returns posts from other authors (the project's own posts are excluded) with engagement metrics.

By default only OUTLIERS are returned: posts that beat their own author's median engagement by at least 2x (outlier_multiplier), so a large account's ordinary post is not reported as viral. minOutlierMultiplier moves that floor (0 opts out and serves every post above minEngagement, including posts with no score yet), mediaFormats narrows to a media shape, and publishedWithinDays sets the recency window.

The feed is searched over meta.published_within_days, restricted to the resolved language and to posts above minEngagement total engagement, then narrowed by the outlier floor and any media shapes. A short or empty data may therefore be those filters at work rather than a topic with no coverage — meta.narrowed_to is present when the caller narrowed beyond the default and the answer is short, and names what to widen; one of those filters may be why, so offer to widen rather than conclude the topic is unwritten.

metrics.views is null whenever LinkedIn did not expose impressions, which is the usual case for another author's post — it is not a zero. permalink and author.profile_url are browsable URLs; id is the internal feed row id and is not accepted by any other endpoint.

Required scope: analytics:read.

Authorization

  • Authorizationstringrequired

    Bearer token in the Authorization header.

    Pass Authorization: Bearer scripe_sk_live_<...> (or scripe_sk_test_<...> for test keys) on every request. Keys are scoped to a single workspace and can be revoked from the Scripe dashboard.

    The same header also accepts an OAuth 2.1 access token (scripe_oat_*); both credentials share one scope vocabulary and every operation below documents the scope it requires. An API key can hold every scope named on this surface except webhooks:manage, which is grantable to OAuth tokens only today — the webhook-endpoint operations answer 403 scope_missing to every API key. Operations that name no scope accept any valid token of the workspace.

Query parameters

  • projectIdstringrequired
  • querystringrequired

    Free-text topic / theme.

  • sortBystring

    Allowed values: relevance, engagement, recent

    Default: "relevance"

  • languagestring

    Allowed values: all, english, german

  • minEngagementinteger

    Default: 100

  • minOutlierMultipliernumber

    Minimum outlier ratio — how far a post beat its OWN author's median engagement. Defaults to 2. Pass 0 to opt out of the outlier floor entirely. The stored ratio is capped at 10, so a value above 10 matches nothing.

    Default: 2

  • mediaFormatsstring

    Comma-separated media shapes to keep. carousel is a swipeable deck (a document post), multi_image several photos in one post, image at most one. An unrecognised value is refused rather than ignored.

  • publishedWithinDaysinteger

    How far back to search, in days.

    Default: 90

  • limitinteger

    Page size. Default 12, max 30. Values above the max are clamped silently; only a non-integer or a value below 1 is rejected with bad_pagination.

    Default: 12

Header parameters

  • Scripe-Api-Versionstring

    Pin the API version. Format YYYY-MM-DD. Omit to receive the currently rolling default. Unknown versions return 400 version_unsupported.

Responses

  • 200

    Ranked viral posts.

  • 400

    Malformed request (bad cursor, bad limit, etc.).

  • 401

    Missing, malformed, expired, or revoked API key.

  • 403

    Plan not eligible, scope missing, or workspace mismatch.

  • 404

    Resource not found in this workspace.

  • 429

    Sliding-window rate limit exceeded.

Example request

bash
curl --request GET \
  --url 'https://api.scripe.io/v1/viral-posts?projectId=<projectId>&query=<query>' \
  --header 'Authorization: Bearer <token>'

Example response (200)

json
{
  "data": [
    {
      "id": "string",
      "content": "string",
      "created_at": "2026-08-10T09:00:00Z",
      "linkedin_post_id": "string",
      "permalink": "string",
      "content_type": "string",
      "post_type": "string",
      "media_format": "carousel",
      "outlier_multiplier": 0,
      "outlier_baseline": "AUTHOR",
      "metrics": {
        "likes": 0,
        "comments": 0,
        "reactions": {
          "appreciation": 0,
          "empathy": 0,
          "interest": 0,
          "maybe": 0
        },
        "total_engagement": 0,
        "views": 0
      },
      "author": {
        "name": "string",
        "slogan": "string",
        "profile_url": "string",
        "handle": "string"
      }
    }
  ],
  "meta": {
    "query": "string",
    "returned": 0,
    "sort_by": "string",
    "language": "string",
    "min_engagement": 0,
    "limit": 0,
    "published_within_days": 0,
    "min_outlier_multiplier": 0,
    "media_formats": [
      "string"
    ],
    "narrowed_to": {
      "min_outlier_multiplier": 0,
      "media_formats": [
        "string"
      ],
      "published_within_days": 0
    }
  }
}