{
  "openapi": "3.0.1",
  "info": {
    "title": "RedNote Creator Monitoring",
    "description": "RedNote Creator Monitoring turns Xiaohongshu (RedNote) into a scheduled, schema-versioned data feed for agencies and analytics teams tracking creator performance, not a hobby scraper.",
    "version": "0.1",
    "x-build-id": "T2WlqULajaxAwq80D"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/protocol~rednote-api/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-protocol-rednote-api",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/protocol~rednote-api/runs": {
      "post": {
        "operationId": "runs-sync-protocol-rednote-api",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/protocol~rednote-api/run-sync": {
      "post": {
        "operationId": "run-sync-protocol-rednote-api",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "creator",
              "post"
            ],
            "type": "string",
            "description": "Which surface to extract.",
            "default": "search"
          },
          "query": {
            "title": "Search query",
            "type": "string",
            "description": "Keyword(s) for mode=search. V1 limitation: a filled keyword query hits /search_result, whose note cards load via RedNote's signed API (deferred — D-007). Anonymous HTTP returns only a thin server-rendered state with NO note cards (zero ok rows — R-003). To get note cards, LEAVE THIS EMPTY to use the discovery feed (/explore), which returns ~25–31 full cards anonymously."
          },
          "creatorUrl": {
            "title": "Creator profile URL",
            "type": "string",
            "description": "RedNote /user/profile/<id> URL for mode=creator. Single URL."
          },
          "creatorUrls": {
            "title": "Creator profile URLs (batch)",
            "type": "array",
            "description": "Array of /user/profile/<id> URLs for mode=creator. Use this for batch extraction (multiple profiles per run).",
            "items": {
              "type": "string"
            }
          },
          "postUrl": {
            "title": "Post URL",
            "type": "string",
            "description": "RedNote /explore/<noteId> URL for mode=post (Bounded Beta). Single URL."
          },
          "postUrls": {
            "title": "Post URLs (batch)",
            "type": "array",
            "description": "Array of /explore/<noteId> URLs for mode=post. Use this for batch extraction. Each entry MUST include its own xsec_token query param (e.g. https://www.xiaohongshu.com/explore/<noteId>?xsec_token=<token>&xsec_source=pc_feed) — entries without one are rejected as malformed (canon 03:16). The single postUrl field is exempt (Mode 3 cookie-only).",
            "items": {
              "type": "string",
              "pattern": "xsec_token=[^&]+"
            }
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Hard CEILING on returned items per run (1–10000) — not a target. There is no pagination in V1: the Actor fetches one page per URL, so search/discovery returns roughly one feed page (~25–31 cards) per run no matter how high this is set. Creator mode scales by the number of creatorUrls (first-tab note cards per profile); post mode returns 1 row per URL. Counts OUTPUT ROWS across the whole run, not per URL — with several creatorUrls a low value may exhaust the budget before later URLs are fetched (skipped URLs are reported in the run diagnostics).",
            "default": 100
          },
          "sort": {
            "title": "Sort order",
            "enum": [
              "relevance",
              "recent",
              "popular"
            ],
            "type": "string",
            "description": "Sort order for search results. Not yet wired into the outgoing request (tracked as D-3) — accepted for forward compatibility only."
          },
          "region": {
            "title": "Region hint (bounded)",
            "type": "string",
            "description": "Bounded targeting hint, not a guarantee. Not yet wired into the outgoing request (tracked as D-3) — accepted for forward compatibility only."
          },
          "language": {
            "title": "Language hint (bounded)",
            "type": "string",
            "description": "Bounded language hint for results. Not yet wired into the outgoing request (tracked as D-3) — accepted for forward compatibility only."
          },
          "sessionCookie": {
            "title": "RedNote session cookie (Mode 3 only)",
            "type": "string",
            "description": "Optional. Bring-your-own session for post detail. Stored encrypted, never logged, never written to output. Using it may risk your RedNote account."
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy or custom proxy settings."
          },
          "includeDiagnostics": {
            "title": "Include diagnostics",
            "type": "boolean",
            "description": "Include verbose diagnostic details in the run summary.",
            "default": false
          },
          "dedupe": {
            "title": "Deduplicate across runs",
            "type": "boolean",
            "description": "Skip already-seen notes in subsequent runs — keyed by noteId for discovery cards and by a synthetic key (creator userId + title + cover) for creator-tab cards, which don't carry a noteId. Uses a persistent seen-set in KeyValueStore. Recommended for scheduled/recurring runs.",
            "default": false
          },
          "enableIntelligenceAi": {
            "title": "Enable Tier 3 opt-in LLM enrichment",
            "type": "boolean",
            "description": "OFF by default. Opt-in flag enabling Tier 3 LLM-derived intelligence enrichment (brand-sentiment / theme clustering / creator-fit / cross-source join-keys) on the `intelligence` namespace. When enabled, successful enrichment bills the `intelligence_ai` PPE event. Requires `llmApiKey` when enabled. This flag is intentionally OFF by default and MUST remain OFF by default across future schema versions — a future schema change must NOT silently default it ON (spec risk: opt-in flag survival).",
            "default": false
          },
          "llmApiKey": {
            "title": "LLM API key (BYOK — Tier 3 opt-in)",
            "type": "string",
            "description": "Optional. Bring-your-own LLM API key for Tier 3 enrichment. Required when `enableIntelligenceAi` is true; ignored otherwise. Stored encrypted, never logged, never written to output (canon 08). The Actor NEVER bundles an operator LLM key — BYOK only. Implementer of the validateInput wiring (workflow G): enforce that `enableIntelligenceAi: true` without `llmApiKey` is an INVALID_INPUT rejection (D-015 pattern); do NOT silently fall back to deterministic-only when the flag is on but the key is missing. The endpoint must be Ollama-compatible — set llmBaseUrl too."
          },
          "llmBaseUrl": {
            "title": "LLM base URL (Tier 3)",
            "type": "string",
            "description": "Required when `enableIntelligenceAi` is true. Base URL of an OLLAMA-COMPATIBLE chat endpoint (the Actor POSTs to `<baseUrl>/api/chat`). Example: https://your-ollama-host.example.com. OpenAI/Anthropic keys will NOT work — the endpoint must speak the Ollama chat API. Must be https:// . The Actor never bundles an operator LLM endpoint or key (BYOK only)."
          },
          "brandBrief": {
            "title": "Brand brief for creator-fit scoring (Tier 3 opt-in)",
            "type": "string",
            "description": "Optional. A brand brief used to score `creatorFit` (Tier 3 opt-in LLM). When `enableIntelligenceAi` is on AND this brief is supplied, the model scores each returned creator's fit against it (audience-theme overlap, tone, engagement quality) — the honest version of claim #7 / 'turn discover-creators into a decision product'. When `enableIntelligenceAi` is on but this brief is ABSENT, `creatorFit` is emitted as `null` (the other three Tier-3 subfields — brandSentiment, themeClusters, joinKeys — still compute and `intelligence_ai` still bills). The brief is NOT a credential (not secret), but it is customer input and is NEVER logged or persisted to `RUN_SUMMARY` (canon 08 minimalism). It IS prompt-injection-guarded before any model call (canon 09 §Security — an unsafe brief degrades the whole Tier-3 enrichment to null, no model call). Whitespace-only is treated as absent. Ignored when `enableIntelligenceAi` is false. Amends D-027 (D-028)."
          },
          "outputTransform": {
            "title": "Flexible data transformation (project / flatten / classify)",
            "type": "object",
            "description": "Optional (D-031 / claim #4). Reshape the `data` payload of each delivered row and/or classify the run. Provide as a JSON object with any of three independent knobs, all optional: `fields` (array of dot-paths to KEEP — the row envelope is always kept; unresolvable paths are dropped, never fabricated as null), `flatten` (boolean — flatten nested objects to dot-keyed single-level entries; arrays stay at their leaf key), `classify` (array of dot-paths to group the run's rows by into per-class counts emitted to RUN_SUMMARY; does NOT alter dataset rows). Example: {\"fields\":[\"basicInfo.redId\"],\"flatten\":true,\"classify\":[\"noteCard.type\"]}. `fields`/`flatten` are applied per-row AFTER billing fires on the original entity (charge-safe) and the row is re-validated against output.v1 — a transform that broke the contract is reverted, so a schema-invalid row never reaches the dataset. The transformed row is emitted on the additive `surface: \"transformed\"` oneOf branch (permissive `data: object|null`); schemaVersion is unchanged (2.0.0). `classify` keys are PII-guarded (each tuple component truncated to 80 chars; >100 distinct classes collapse into an `_other` bucket — E-001 / canon 08). Never throws — a bad dot-path or malformed shape degrades to 'no transform'. Absent ⇒ no transform, rows ship on their native surface."
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}