# Search organic content

Search the copied public organic corpus with bounded filters.

## Endpoint: GET /v1/organic

- Method: `GET`
- Path: `/v1/organic`
- Authentication: Bearer API credential or OAuth access token
- Required scope: `context:read`
- MCP tool: `search_organic`
- MCP action: `search`

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `q` | query | string, 1–200 | no | Free-text search. |
| `category` | query | Health & Wellness | Personal Development | Relationships & Lifestyle | Arts, Hobbies & Entertainment | Education & Knowledge | Fashion & Beauty | Spirituality & Beliefs | Business & Finance | Travel | Food & Cooking | Home & Design | Fitness | Technology | Gaming & Esports | Productivity & Organization | no | Exact organic corpus category. |
| `business_type` | query | app | ecommerce | saas | service | affiliate | other | creator | game | book | unclassified | no | Exact business-type filter. |
| `platform` | query | tiktok | instagram | threads | no | Organic platform filter. |
| `content_type` | query | slideshow | video | mixed | no | Content-type filter. |
| `account` | query | string, 1–200 | no | Creator account filter. |
| `product` | query | string, 1–200 | no | Exact product-name filter. |
| `store_ids` | query | comma-separated numeric App Store ids, 1–100 | no | Posts PeekPanda tied to any of these apps, such as every app on a board. |
| `max_slides` | query | integer, 1–100 | no | Maximum slide count. |
| `ad` | query | ads | likely_or_ads | not_ads | no | TikTok paid reach: posts TikTok served as ads, also likely ads (Spark Ads authorized or paid-reach engagement), or neither. Unchecked posts count as not ads. |
| `creator_sponsored` | query | boolean | no | true for posts a brand paid a creator to make, false to hide them. Unchecked posts count as not sponsored. |
| `language` | query | comma-separated ISO 639-1 codes | no | Posts in any of these languages, such as en,es. mul is bilingual, zxx has no spoken or written words, und is undetermined. |
| `published_since` | query | date, YYYY-MM-DD | no | Inclusive calendar start date. |
| `published_until` | query | date, YYYY-MM-DD | no | Inclusive calendar end date; must be at or after published_since. |
| `sort` | query | relevance | newest | latest_posted | most_views | most_likes | most_comments | most_slides | no | Defaults to relevance when q is set and newest otherwise. |
| `limit` | query | integer, 1–40 | no | Page size; defaults to 12. offset + limit cannot exceed 1000. |
| `offset` | query | integer, 0–960 | no | Result offset; defaults to 0. |

## Known errors

- 400 invalid_request for an invalid filter, identity or limit.
- 401 authentication_required for a missing or invalid credential.
- 402 subscription_required when access is not entitled.
- 403 authorization_required for a missing scope or unavailable preview access.
- 403 workspace_not_accessible when x-genviral-tenancy names a workspace the credential cannot reach.
- 404 not_found when the record is outside the accessible catalogue.
- 429 rate_limited; honor Retry-After when present.
- 429 daily_call_limit; the plan's daily API and MCP calls are used until 00:00 UTC.

## Request

Send filters as query parameters. This read serves stored corpus rows and does not scrape TikTok.

```
curl --get 'https://api.peekpanda.com/v1/organic' \
  --header "Authorization: Bearer $PEEKPANDA_TOKEN" \
  --header 'x-genviral-tenancy: personal' \
  --data-urlencode 'q=meal planner' \
  --data-urlencode 'platform=tiktok' \
  --data-urlencode 'limit=12'
```

## MCP request

Call search_organic with action search. Path fields go in params, filters in query, and a write body in body.

```
{
  "name": "search_organic",
  "arguments": {
    "request": {
      "action": "search"
    }
  }
}

```

## Response

posts is a page of organic corpus rows. product_app is null when no catalogue app was matched; product_app.matchedBy = product_name means a conservative inferred association, not verified ownership. slide_texts is null on list results. relevance is always null. next_offset is null on the last page or when the offset cap is reached.

```
{
  "posts": [
    {
      "id": "organic-post-example",
      "platform": "tiktok",
      "content_type": "slideshow",
      "link": "https://www.tiktok.com/@example/video/1",
      "category": "Food & Cooking",
      "business_type": "app",
      "product_name": "Example Meal Planner",
      "product_website": "https://example.com",
      "product_app": {
        "platform": "ios",
        "storeId": "6480417616",
        "appName": "Example Meal Planner",
        "iconUrl": "https://is1-ssl.mzstatic.com/example-meal-planner.jpg",
        "matchedBy": "product_name"
      },
      "account": "example",
      "caption": "five dinners in ten minutes",
      "hashtags": [
        "#cooking",
        "#mealprep"
      ],
      "date_published": "2026-04-02",
      "metrics": {
        "views": 412000,
        "likes": 31000,
        "comments": 480,
        "shares": 210,
        "bookmarks": 9400
      },
      "slide_count": 7,
      "preview_image_url": "https://cdn.example.com/preview.jpg",
      "image_urls": [
        "https://cdn.example.com/preview.jpg"
      ],
      "video_url": null,
      "hook_text": "I stopped meal planning and did this instead",
      "hook_analysis": {
        "content_class": "listicle_hook",
        "format_template": "I stopped X and did Y",
        "psychology_tags": [
          "curiosity",
          "relief"
        ]
      },
      "search_summary": "A slideshow about weeknight cooking for a meal-planning app.",
      "niche": "meal planning",
      "topics": [
        "cooking",
        "meal prep"
      ],
      "search_keywords": [
        "dinner ideas",
        "meal planner app"
      ],
      "ad_signal": null,
      "creator_sponsored": false,
      "language": "en",
      "slide_texts": null,
      "relevance": null
    }
  ],
  "total": 1,
  "has_more": false,
  "next_offset": null
}

```

## Source

Stored public organic content with its original source identity and observation date.

## Refresh

This read returns stored content and does not begin collection.
