# ReplyNodes developer docs — full source index # ReplyNodes developer docs ReplyNodes is the read-only web context API for AI agents: search, scrape and read public web, social and app data through one REST API or remote MCP server. The canonical REST host is api.replynodes.com; discover live data operations with https://api.replynodes.com/v1/capabilities. Provider operations are authenticated HTTP GETs; the keyless exceptions are listed below. ## Choose an integration - **REST** — use the exact GET path and parameters from the API Reference, send `Authorization: Bearer ${REPLYNODES_API_KEY}`, and preserve the { data, meta } envelope. - **MCP** — use the remote Streamable HTTP server at https://mcp.replynodes.com/mcp when your client supports MCP; interactive clients use native Better Auth MCP OAuth, and headless or manual setups fall back to a Bearer API key through the client secret mechanism. - **SDK** — this repository contains OpenAPI Generator targets for TypeScript, Python, Go, Ruby, and PHP; verify each downstream package before installing it. - **Agent integrations** — REST works with coding agents and tool functions; MCP-capable clients include Claude Code, Cursor, Codex, VS Code, Hermes, and OpenCode. ChatGPT uses a GPT Action/REST path rather than MCP. ## Authentication ReplyNodes has two first-class authentication options: native Better Auth MCP OAuth at https://auth.replynodes.com for interactive MCP clients, and API keys for headless, manual, and REST use. Sign in at https://platform.replynodes.com/sign-in. For the agent claim flow, give the human the exact verification link, then store the returned key once as `REPLYNODES_API_KEY`; see https://replynodes.com/auth.md. Keep the key server-side and never put it in a URL, prompt, browser bundle, log, or commit. ## No key / With key Only the following capabilities have keyless routes. At the daily limit the API returns `429 anonymous_limit_reached`; the claim flow at https://replynodes.com/auth.md gives an agent a key. | Capability | Tier | Daily anonymous limit | | --- | --- | ---: | | brand-logo | Tier A | 20/day | | app-store-api | Tier B | 10/day | | google-play-api | Tier B | 10/day | | reddit-api | Tier B | 10/day | | youtube-api | Tier B | 10/day | | web-search | Tier B | 10/day | | web-scraping | Tier B | 10/day | | company-research | Tier C | 3/day | | competitor-research | Tier C | 3/day | With a key, use the read-only provider GET/HEAD routes and the routes documented by the live capability contract. ## Live capability groups - **Apple App Store (apps, ratings, reviews, search)**: 9 GETs; inspect the API Reference for the exact path and parameters. - **Brand intelligence (retrieve, search, styleguide, fonts, logo)**: 6 GETs; inspect the API Reference for the exact path and parameters. - **Google Play public app data**: 11 GETs; inspect the API Reference for the exact path and parameters. - **Hacker News public stories, search, items, and users**: 9 GETs; inspect the API Reference for the exact path and parameters. - **markdown**: 1 GET; inspect the API Reference for the exact path and parameters. - **PDF to Markdown for AI agents (read PDF, extract PDF text, and PDF context)**: 1 GET, 1 HEAD, 1 POST; inspect the API Reference for the exact path and parameters. - **Reddit public posts, search, subreddits, and users**: 6 GETs; inspect the API Reference for the exact path and parameters. - **Anonymous research workflows (company and competitor dossiers)**: 2 GETs; inspect the API Reference for the exact path and parameters. - **Web search**: 1 GET; inspect the API Reference for the exact path and parameters. - **Web extraction (scrape, crawl/map, and page context)**: 4 GETs; inspect the API Reference for the exact path and parameters. - **YouTube public videos, channels, comments, playlists, related videos, search, and transcripts**: 7 GETs; inspect the API Reference for the exact path and parameters. ## Start here - [Agent Quickstart](https://docs.replynodes.com/docs/agent-quickstart) · [Markdown](https://docs.replynodes.com/docs/agent-quickstart.md) - [Quickstart](https://docs.replynodes.com/docs/quickstart) · [Markdown](https://docs.replynodes.com/docs/quickstart.md) - [Authentication](https://docs.replynodes.com/docs/auth) · [Markdown](https://docs.replynodes.com/docs/auth.md) - [MCP setup](https://docs.replynodes.com/docs/mcp) · [Markdown](https://docs.replynodes.com/docs/mcp.md) - [API Reference](https://docs.replynodes.com/reference) - [Canonical OpenAPI JSON](https://docs.replynodes.com/api/openapi.json) - [ReplyNodes on GitHub](https://github.com/replynodes) ## Provider guides - [Web extraction](https://docs.replynodes.com/docs/guides/web) · [Markdown](https://docs.replynodes.com/docs/guides/web.md) - [Web search](https://docs.replynodes.com/docs/guides/search) · [Markdown](https://docs.replynodes.com/docs/guides/search.md) - [Brand intelligence](https://docs.replynodes.com/docs/guides/brand-intelligence) · [Markdown](https://docs.replynodes.com/docs/guides/brand-intelligence.md) - [Brand Kit](https://docs.replynodes.com/docs/guides/brand-kit) · [Markdown](https://docs.replynodes.com/docs/guides/brand-kit.md) · WHEN TO USE: generate a local, inspectable brand context from one bare domain · Canonical source: https://github.com/replynodes/brand-kit - [YouTube](https://docs.replynodes.com/docs/guides/youtube) · [Markdown](https://docs.replynodes.com/docs/guides/youtube.md) - [Apple App Store](https://docs.replynodes.com/docs/guides/app-store) · [Markdown](https://docs.replynodes.com/docs/guides/app-store.md) - [Google Play](https://docs.replynodes.com/docs/guides/google-play) · [Markdown](https://docs.replynodes.com/docs/guides/google-play.md) - [Reddit](https://docs.replynodes.com/docs/guides/reddit) · [Markdown](https://docs.replynodes.com/docs/guides/reddit.md) The generated llms-full.txt contains the source-backed page text. Provider availability, route names, schemas, and billing can change; re-read the live capability document before making a call. --- # Agent Quickstart > Pick REST, an SDK, MCP, or an agent skill. Source page: https://docs.replynodes.com/docs/agent-quickstart # Agent Quickstart Choose in this order: 1. **Have a key?** Use REST with `REPLYNODES_API_KEY`, or use MCP if your client supports it. 2. **Have a key and an MCP-capable client?** Connect to `https://mcp.replynodes.com/mcp` and configure the key through the client's secret mechanism. 3. **No key?** Follow the [agent claim flow](https://docs.replynodes.com/docs/auth), or read the full protocol at [https://replynodes.com/auth.md](https://replynodes.com/auth.md). A human must approve the exact `verification_uri_complete` link once. 4. **Just trying the service?** Use only the documented keyless capabilities and their daily limits below; all other provider reads require a key. ## Keyless capabilities | Capability | Tier | Daily anonymous limit | | --- | --- | ---: | | brand-logo | Tier A | 20/day | | app-store-api | Tier B | 10/day | | google-play-api | Tier B | 10/day | | reddit-api | Tier B | 10/day | | youtube-api | Tier B | 10/day | | web-search | Tier B | 10/day | | web-scraping | Tier B | 10/day | | company-research | Tier C | 3/day | | competitor-research | Tier C | 3/day | Only these listed capabilities have keyless routes. At the limit, the API returns `429 anonymous_limit_reached`; use the claim flow for a key. | Option | Use it when | Source of truth | | --- | --- | --- | | REST | You control the HTTP call or tool function | OpenAPI + API Reference | | SDK | A generated downstream package is available to your team | `sdk-generation/` configs and canonical OpenAPI | | MCP | Your client can connect to a remote Streamable HTTP server | [MCP guide](https://docs.replynodes.com/docs/mcp) and generated MCP inventories | | Agent Skill | Your client reads instruction packages | `services/social-data-skills/generated/` | ## REST tool Expose a function that performs a `GET` against the exact path from the OpenAPI document, adds an `Authorization: Bearer ${REPLYNODES_API_KEY}` header from a secret store, passes only declared parameters, and returns the JSON envelope. Do not let an agent turn a read operation into a write operation. ## SDK path This repository does not publish SDK implementations. It does contain the pinned generation target list in `sdk-generation/README.md`: TypeScript (`@replynodes/sdk`), Python (`replynodes`), Go (`github.com/replynodes/replynodes-go`), Ruby (`replynodes`), and PHP (`replynodes/replynodes`) are downstream synchronization targets, not packages you can assume are installable from this repo. Verify package availability and the generated client's auth configuration before using one. ## Client choice Claude Code, Cursor, Codex, VS Code, Hermes, and OpenCode can all use the REST pattern. MCP-capable clients can use [MCP](https://docs.replynodes.com/docs/mcp) with native OAuth or a ReplyNodes API key. For skill-aware clients, install or reference the generated package that matches the provider; the package's `SKILL.md`, `INSTALL.md`, and `references/` files are authoritative. Do not copy stale endpoint lists into prompts. --- # API Reference > The interactive reference for the canonical OpenAPI contract. Source page: https://docs.replynodes.com/docs/api-reference # API Reference Use the interactive reference at [/reference](https://docs.replynodes.com/reference). It is backed by the runtime capability OpenAPI contract copied to `/api/openapi.json` during the docs build, preserving the deployed paths, schemas, and provider grouping. Test requests only against a safe, read-only environment and use a key with the intended entitlement. The same contract carries the two authenticated lifecycle surfaces: `/v1/monitors`, and the Company Changes surface under `/v1/watches`, `/v1/events`, `/v1/entities`, and `/v1/intelligence`. `GET` operations require the `monitors:read` scope and the Watch lifecycle writes (`POST /v1/watches`, `PATCH /v1/watches/{id}`) require `monitors:write`; a request without the required scope returns `403 forbidden_scope` with a request ID. There is no public `DELETE`: archive a Watch with `PATCH /v1/watches/{id}` and `{"status":"archived"}`, which is terminal and only an idempotent replay of itself. Watch topic changes are temporal subscription intervals, so disabling a topic stops future observation while its retained history stays readable. Canonical Events are shared public-web intelligence, while a Watch — its id, cadence, topics, and webhook destination — is private to the organization that created it; an object belonging to another organization returns `404`. --- # Authentication > Configure the API key without exposing it. Source page: https://docs.replynodes.com/docs/auth # Authentication ReplyNodes has two first-class authentication options: - **MCP OAuth** — interactive MCP clients use Better Auth at [`https://auth.replynodes.com`](https://auth.replynodes.com) with the `mcp:read` scope. - **API key** — headless clients, CI, SDKs, and manual MCP configurations use an `rn_test_*` or `rn_live_*` key. OAuth access is resolved to the authenticated ReplyNodes organization. Clients must not send an organization id, and API keys remain supported alongside OAuth. Sign in or manage access at [`https://platform.replynodes.com/sign-in`](https://platform.replynodes.com/sign-in) and manage access at [`https://platform.replynodes.com/api-keys`](https://platform.replynodes.com/api-keys). The canonical OpenAPI document defines HTTP Bearer authentication for the public API. Send the raw key after the `Bearer` scheme in the `Authorization` header. Key formats documented by the contract are `rn_test_<64hex>` and `rn_live_<64hex>`; never place a real key in a URL, browser bundle, prompt, log, or repository. The gateway CLI reads `FETCHER_API_KEY` and constructs this header for requests. Other clients should use their secret-store equivalent and follow the same HTTP header contract. See [Quickstart](https://docs.replynodes.com/docs/quickstart) for a request that fails closed when the environment variable is absent. ## Agents Agents obtain a read-only API key through a short claim approved once by a human. Start a claim with: ```bash curl -sS -X POST https://platform.replynodes.com/api/agent/claim \ -H 'Content-Type: application/json' \ -d '{"agent_name":"my-agent","agent_platform":"my-platform"}' ``` `agent_name` and `agent_platform` are optional labels. A successful response contains `claim_id`, `device_code`, `user_code`, `verification_uri`, `verification_uri_complete`, `expires_in` (`900` seconds, or 15 minutes), `interval` (`3` seconds), and `docs`. Give the human the exact `verification_uri_complete` link: it already includes the `user_code`. Wait for that one approval, then poll at the returned interval: ```bash curl -sS -X POST https://platform.replynodes.com/api/agent/claim/token \ -H 'Content-Type: application/json' \ -d "{\"claim_id\":\"${CLAIM_ID}\",\"device_code\":\"${DEVICE_CODE}\"}" ``` On `200`, store `api_key` once as `REPLYNODES_API_KEY`; never log it or ask the token endpoint for it again. The returned `expires_at` is authoritative. The default issued `agent_read` key lifetime is 30 days. If a later API call returns `401`, start a new claim. The historical scope name is `read:x_public`; it means public provider reads and is not a request to rename the scope. An agent key reaches only read-only provider `GET` and `HEAD` routes, `/v1/capabilities`, and the provider `/v1/x` surface where that surface is covered by provider-read routing. It cannot use non-`GET` methods or key, dashboard, internal, billing, wallet, checkout, webhooks, usage, overview, or me routes. Check `/v1/capabilities` for the current provider contract; this page does not promise PDF conversion or another route outside that allowlist. ### Token polling outcomes In this table, `—`/omitted status means the response body does not include the `status` field. The status is omitted on paths where the code does not return it, including some `503 temporarily_unavailable` responses. | HTTP | `error` | `status` | `Retry-After` | Agent action | | ---: | --- | --- | --- | --- | | 200 | — | `approved` / `state: revealed` | — | Store `api_key` once with its `expires_at`; stop polling. | | 428 | `authorization_pending` | `pending` | — | Wait `interval` seconds, then poll again. | | 429 | `poll_rate_limited` | — | Returned header | Wait for `Retry-After`; do not loop faster. | | 409 | `already_delivered` | `delivered` | — | Stop; the key was already revealed. Use the dashboard recovery details. | | 409 | `already_delivered` | `delivery_uncertain` | — | Do not start a new claim blindly; check with the human / [Agent keys page](https://platform.replynodes.com/api-keys#agent-keys); then start a new claim if the key was not stored. | | 410 | `expired_token` | `expired` when present | — | Stop and start a new claim. | | 403 | `authorization_failed` | `authorization_failed` when present | — | Stop; after human approval, restart the claim. | | 404 | `invalid_claim` | — | — | The claim id or device code is invalid; stop and start a new claim. | | 503 | `temporarily_unavailable` | `delivery_uncertain` when returned; omitted on some paths | Returned header when present | Wait and retry while claim recovery remains possible. | | 503 | `delivery_uncertain` | — | — | Retry while claim recovery remains possible. | | 409 | `delivery_uncertain` | `delivery_uncertain` | — | Retries are exhausted; stop and use dashboard recovery. | For the complete protocol, use [`https://replynodes.com/auth.md`](https://replynodes.com/auth.md). --- # App Store > Read public Apple App Store listings and reviews. Source page: https://docs.replynodes.com/docs/guides/app-store # App Store The `appStore` tag covers search, suggestions, app details, developer listings, collections, privacy, ratings, reviews, and similar apps under `/v1/appstore/*`. The operation names and parameter spellings are case-sensitive in the generated [API Reference](https://docs.replynodes.com/reference). Use this guide when an agent needs a normalized view of publicly available Apple App Store information without opening a private account or relying on a browser session. Start with search or suggestions when the app identifier is unknown, then use the detail operation to resolve the canonical listing and its metadata. Developer and collection routes help expand a result set, while privacy, ratings, reviews, and similar-app operations provide focused enrichment for research workflows. Keep the identifier, country, language, and pagination values returned by one request when following links into another operation; changing locale can change the visible listing and review set. Responses are read-only and should be treated as a snapshot of public upstream data, not as a guarantee of availability or a substitute for App Store policy documentation. For exact request shapes, required fields, and response envelopes, consult the generated [API Reference](https://docs.replynodes.com/reference). Use the runtime capability document as the final authority when deployed routes differ from examples. Preserve `request_id` values in automated jobs so an operator can trace a failed read, and handle ordinary rate-limit or upstream-availability responses with bounded retries rather than repeatedly replaying every request. --- # Brand intelligence > The canonical contract for authenticated Brand Intelligence routes and the anonymous aggregate brand read. Source page: https://docs.replynodes.com/docs/guides/brand-intelligence # Brand intelligence The repository README contains the owned GitHub core entry point into this loop, with bounded `source=github`, `utm_medium=owned`, and `utm_campaign=core` attribution. This page is the canonical public contract for Brand Intelligence, including the v0.1.1 external npm CLI aggregate read. It describes two intentionally different surfaces: - The authenticated, metered `GET /v1/brand/retrieve`, `GET /v1/brand/search`, `GET /v1/brand/logo`, `GET /v1/brand/fonts`, and `GET /v1/brand/styleguide` routes on `api.replynodes.com`. - The one anonymous aggregate read on the dedicated host: `GET https://brand.replynodes.com/{bare-domain}`. The canonical OpenAPI contract remains [`services/replynodes-fetcher/internal/gateway/capabilities.openapi.json`](https://github.com/replynodes/replynodes-fetcher/blob/main/services/replynodes-fetcher/internal/gateway/capabilities.openapi.json) for the `/v1` routes: it is the source of their paths, parameters, schemas, security, and standard `{data, meta}` response envelope. The dedicated-host aggregate is intentionally not an anonymous `/v1` route and is specified here because it has a separate path grammar, direct response object, quota, and cache policy. `GET /v1/webcontext/brand` remains a separate authenticated, metered operation governed by OpenAPI. None of these `/v1` routes is anonymous; do not infer anonymous access to any `/v1/brand/*` route from the aggregate contract. ## Brand Kit CLI The approved v0.1.1 npm release target is the scoped package `@replynodes/brand-kit`. Run it without an install using: ```sh npx @replynodes/brand-kit ``` The installed executable remains `brand-kit`; the unscoped `brand-kit` package name was blocked by npm similarity policy because it was too similar to the existing `brandkit` package. The GitHub repository remains `replynodes/brand-kit`, and the runtime endpoint remains `GET https://brand.replynodes.com/{bare-domain}`. No API key or signup is required, and the CLI preserves one request and read-only behavior. The old unpublished GitHub v0.1.0 release/tag is historical. The approved v0.1.1 package is published and current; a separate v0.1.2 keyword patch is also published. ## Anonymous aggregate endpoint The v0.1.1 CLI uses exactly this endpoint: ```text GET https://brand.replynodes.com/{bare-domain} ``` It requires no account and no API key. The path value is one bare, public DNS domain. An optional single trailing slash is accepted. The query string is ignored, so it must not be used for versioning or options. Normalization is deterministic: trim surrounding whitespace, lowercase, strip one leading `www.`, and strip one trailing DNS dot. Embedded whitespace and control characters are rejected rather than trimmed. The resulting hostname must be an ASCII hostname of at least two dot-separated labels and no more than 253 characters total; each label is 1–63 characters, starts and ends with an ASCII letter or digit, and permits hyphens only in the interior. Normalization is used for the upstream lookup and cache key. Accepted examples: ```text /stripe.com /WWW.Stripe.com/ /stripe.com. /stripe.com?anything=ignored ``` Rejected examples (all return `400`): ```text /https://stripe.com # scheme /stripe.com:443 # port /stripe.com/docs # path /@user:password@stripe.com # credentials /localhost # local name /127.0.0.1 # IP literal /169.254.169.254 # metadata/private address ``` Canonical and non-canonical IP spellings, cloud-metadata names, malformed labels, and whitespace/control characters are rejected before an upstream brand fetch. The resolution-level SSRF guard validates the initial DNS resolution and rejects a non-public address. The pinned runtime then performs its own separate fetch/resolution, so a residual DNS-rebinding TOCTOU risk remains; this guard is not absolute protection against rebinding. ## Successful response The response is a direct JSON object with `Content-Type: application/json; charset=utf-8`. It is not wrapped in `data`. Unknown keys must be ignored by clients. The exact top-level keys are: | Key | Type | Presence and meaning | | --- | --- | --- | | `domain` | string | Always present; normalized lookup domain. | | `url` | string | Always present; canonical target URL used for extraction. | | `name` | string | Optional detected brand/site name. | | `description` | string | Optional public description. | | `favicon` | string | Optional favicon URL. | | `og_image` | string | Optional Open Graph/image URL. | | `primary_logo` | string | Optional primary logo URL or inline asset value. | | `logos` | array of objects | Optional logo assets. Each item has `url` (string) and may have `kind` (string). | | `colors` | array of objects | Optional colors. Each item has `hex` (string), and may have `usage` (string) and `count` (integer). | | `fonts` | array of strings | Optional detected font families. | | `social_links` | array of strings | Optional links from supported social hosts. | | `backdrops` | array of objects | Optional hero/banner/cover assets, with the same item shape as `logos`. | | `styleguide` | object | Optional merged styleguide; see below. | | `meta` | object | Always present; aggregate response metadata. | Absent fields are normal. An absent field means the public source did not provide a usable value; it is not an error. Clients must not assume that an empty logo, color, font, social-link, backdrop, or styleguide collection is available, and should generate local outputs around whatever subset is present. `meta` has these keys and types: | Key | Type | Meaning | | --- | --- | --- | | `domain` | string | Same normalized domain as the top-level `domain`. | | `cached` | boolean | `false` for a fresh aggregate build; `true` when served from the shared cache. | | `fetched_at` | string | UTC RFC 3339 timestamp for the cached/fresh aggregate build. | | `cache_ttl_seconds` | integer | `86400` for successful aggregate responses. | | `source` | string | `brand-intelligence`. | | `docs` | string | Canonical documentation URL. | ### Styleguide When styleguide extraction succeeds, `styleguide` is an object containing `domain` (string), `url` (string), `status` (string), and any available `mode`, `colors`, `typography`, `buttons`, `card`, `spacing`, `shadows`, and `radii` fields. Those nested collections and properties are optional. The `status` values are: - `extracted`: usable CSS/style blocks and design signals were extracted. - `partial`: some style signals were found, but the result is incomplete. - `unavailable`: the page was reachable but no usable styleguide signals were available. If the separate styleguide fetch itself fails, the aggregate still returns the successfully retrieved brand fields and omits the `styleguide` key. A styleguide failure does not turn an otherwise successful brand aggregate into an error. A present `styleguide` with `status: "unavailable"` is a valid successful result and is different from a failed styleguide fetch. ### Asset kinds and values Every `logos[].kind` and `backdrops[].kind` is normalized from an extraction slot and an asset format. When the slot is non-empty and differs from the format, the result is `.`; when the slot is empty, the format is returned alone; and when the slot already equals the format, the slot-only value is returned (for example, `svg`). For HTTP(S) URLs, the format is taken from the URL path and is one of `ico`, `png`, `svg`, `jpg`, `jpeg`, `webp`, `avif`, `gif`, or the fallback `image`. Non-HTTP(S) values, including inline assets, use the `inline` format. Thus different files from the same slot remain distinguishable, such as `favicon.svg`, `favicon.ico`, and `apple-touch-icon.png`, while slot/format combinations follow the rules above. Treat non-HTTP(S) values as opaque data/references: do not fetch them as URLs. Only fetch or download asset values beginning with `http://` or `https://`; preserve other values for a later local rendering decision. ## HTTP behavior and errors The aggregate supports `GET` and `HEAD`. `HEAD` performs the same contract checks and reports the `Content-Length` of the corresponding `GET` JSON representation, but sends no response body. Successful JSON responses include `Cache-Control: public, max-age=86400`, and `Access-Control-Allow-Origin: *`. Other methods return `405` with `Allow: GET, HEAD`. Errors use the standard object envelope: ```json { "error": { "code": "invalid_request", "message": "The request is malformed or contains invalid parameters.", "request_id": "..." } } ``` The contract-level statuses are: | Status | Code | Exact message | | --- | --- | --- | | `400` | `invalid_request` | `The request is malformed or contains invalid parameters.` | | `405` | `method_not_allowed` | `This endpoint only supports GET requests.` | | `404` | `not_found` | `The requested resource was not found.` | | `429` | `rate_limited` | `The rate limit for this workspace or API key has been exhausted.` | | `502` | `upstream_unavailable` | `The data provider is temporarily unavailable.` | | `503` | `degraded` | `Authorization is temporarily unavailable; try again shortly.` | | `504` | `gateway_timeout` | `The request could not be completed within the allowed time.` | The `request_id` value is deployment-generated and should be retained for support or diagnostics. `HEAD` sends no response body; clients should use the status and headers. The `404 not_found` case means the dedicated route is unavailable or not configured on that deployment; it does not indicate invalid input. ## Cache, quota, and failure behavior The anonymous quota is the shared capability-aware Tier A quota for the canonical `brand-kit` capability: a fixed **20 requests per UTC calendar day per trusted client-IP bucket**. The bucket identifier is derived from the trusted client IP, the canonical capability, and the UTC date, and it lives in the shared Redis counter namespace — the same engine and storage used by the anonymous Markdown route, not a separate provider-specific minute counter. Domain validation runs before admission, so a malformed or rejected request is answered with `400` and never consumes a quota unit. Once admitted, a cache hit and an upstream failure each consume exactly one daily unit. Successful aggregate responses are stored in the shared Redis cache for 24 hours. `X-Cache: miss` identifies a fresh build and `X-Cache: hit` identifies a cached response. Responses expose: ```text X-RateLimit-Limit: 20 X-RateLimit-Remaining: X-RateLimit-Reset: ``` When the quota is exhausted, the response is `429` and includes `Retry-After` in seconds until the next UTC midnight. A separate, generic per-IP **burst safeguard** of 20 requests per minute also applies to every brand-host request, anonymous or keyed. It is not product quota: it never consults or decrements the `brand-kit` capability bucket, it is not metered or billed, and when it trips the route returns the generic `429 rate_limited` (with `Retry-After`), never `anonymous_limit_reached`. It absorbs abusive bursts, including from keyed callers who are not subject to the anonymous daily quota; the `X-RateLimit-*` headers describe the product quota, not this generic safeguard. Missing, unavailable, or failed Redis is fail-closed: the route returns `503 degraded` rather than using a process-local limiter, bypassing the cache, or serving an uncached anonymous upstream request. Cache read and write failures are also degraded responses. The gateway’s shipped default outer handler timeout is 15 seconds. Normally, the configured 15-second handler timeout yields a 12-second brand-fetch budget. Otherwise, subtract 3 seconds from the configured handler timeout, apply a 5-second floor, then cap the result at the outer handler timeout, so configured outer handler timeouts below 5 seconds yield that outer timeout. A non-positive configuration falls back to the shipped 15-second default. The subsequent cache `SET` uses `context.WithoutCancel` with no separate deadline, so it is not guaranteed to finish before the outer deadline; an outer handler timeout can still yield `504 gateway_timeout`. Upstream failure maps to `502 upstream_unavailable`; a fetch or request deadline maps to `504 gateway_timeout`; and cache read or write failure maps to `503 degraded`. SSRF and public-address checks apply before upstream extraction, subject to the residual DNS-rebinding risk described above. No provider credentials, cookies, sessions, or write operation are part of this endpoint. ## Verification and evidence Production verification can use safe, read-only requests: ```sh curl -sS -D /tmp/brand.headers \ -o /tmp/brand.json \ 'https://brand.replynodes.com/stripe.com' curl -sS -I 'https://brand.replynodes.com/stripe.com' curl -sS -D - -o /dev/null \ 'https://brand.replynodes.com/stripe.com?probe=ignored' ``` Confirm the status, JSON content type, `domain`/`url`/`meta`, cache and rate limit headers, and that the `HEAD` response has no body while its `Content-Length` matches the corresponding GET representation. A second GET for the same normalized domain should be a cache hit when the cache is warm. Do not send API keys or other secrets. When recording evidence, redact client IP details, cookies, authorization material, internal hostnames, and any unbounded request or response metadata; retain status, relevant public headers, request ID, and a redacted response shape. This repository currently defines the production hostname `brand.replynodes.com`; it does **not** define a public staging or testnet brand hostname. Do not invent one. For a staging/testnet deployment, an operator must first provide the deployment’s explicitly configured public brand host, then run the same safe checks against that host and record the configured host and redacted evidence. Internal service addresses are not public CLI endpoints. ## Compatibility and CLI boundary The external npm CLI v0.1 should treat this direct object as an additive, forward-compatible contract: tolerate omitted optional fields and unknown future fields, and require only `domain`, `url`, and `meta` for a structurally valid success. Additive fields do not require a new CLI endpoint or a new versioned path. There is no query-based API versioning and no API-key mode for the aggregate endpoint. After fetching, CLI outputs are generated locally. These are CLI concerns, not additional API response contracts: ```text brand.json colors.json fonts.json logo references tokens.css DESIGN.md ``` ## Non-goals - No anonymous `/v1` brand routes. - No account or API key for the aggregate read. - No new aggregation backend service or endpoint. - No change to the authenticated/metered `/v1/brand/retrieve`, `/v1/brand/search`, `/v1/brand/logo`, `/v1/brand/fonts`, or `/v1/brand/styleguide` routes. - No server-side generation of the npm CLI’s local artifacts. ## Cross-discovery and returning-caller CTA Successful anonymous aggregate responses include `X-ReplyNodes-Discovery: markdown` and a `Link` relation to `https://md.replynodes.com/{domain}`. A valid returning `rn_anon_caller_id` cookie also exposes `X-ReplyNodes-CTA: api-key` and a `Link` relation to `https://platform.replynodes.com/sign-up`. These are informational response headers; no signup or API key is required before the free read. --- # Brand Kit > Generate a local, inspectable brand kit from one bare domain. Source page: https://docs.replynodes.com/docs/guides/brand-kit # Brand Kit Run the exact command `npx @replynodes/brand-kit ` to generate a local brand kit from one public domain. The sole endpoint boundary is `GET https://brand.replynodes.com/{bare-domain}`. The command produces exactly six local outputs: `brand.json`, `colors.json`, `fonts.json`, `logos.json`, `tokens.css`, and `DESIGN.md`. These files are a local transformation of the aggregate response; they are not additional API routes. See the [Brand intelligence aggregate contract](https://docs.replynodes.com/docs/guides/brand-intelligence) for the response and validation rules. ## Current source path The published package is available at v0.1.1. If npm is unavailable in a restricted environment, use this distinct source/clone fallback from the canonical [ReplyNodes Brand Kit repository](https://github.com/replynodes/brand-kit): ```sh git clone https://github.com/replynodes/brand-kit.git cd brand-kit npm ci node bin/brand-kit.mjs ``` The input is one bare domain, not a URL, path, port, query, fragment, IP literal, `localhost` name, or credential-bearing value. ## WHEN TO USE Use Brand Kit when a person or agent needs a small, reviewable brand context before making design decisions. It is useful when the consumer can work from the six generated files and wants missing or partial source signals to remain visible rather than guessed. ## Intent map ### 1. Build a landing page with an agent **Command/input:** Run `npx @replynodes/brand-kit linear.app` with the landing page’s bare-domain input. **Artifacts:** Review all six outputs—`brand.json`, `colors.json`, `fonts.json`, `logos.json`, `tokens.css`, and `DESIGN.md`. **Consumer workflow:** Give the agent the files as inspectable context, then have it propose page structure and styling while a person reviews the source signals. **Limitations:** This supplies references and available signals only; it does not guarantee a design result, download logo binaries, add credentials, or download logo binaries. Missing or partial data remains explicit, and no credentials are requested. ### 2. Generate a brand kit **Command/input:** Run `npx @replynodes/brand-kit vercel.com` for the one bare domain that should be documented. **Artifacts:** Consume exactly `brand.json`, `colors.json`, `fonts.json`, `logos.json`, `tokens.css`, and `DESIGN.md`. **Consumer workflow:** Keep the six files together as a local, inspectable reference package and read the provenance and caveats before using any value. **Limitations:** No API key or signup is required, but the command has no anonymous `/v1` routes, no credentials, and no promise that every source field is present; unavailable data stays explicit. ### 3. CSS/design-token handoff **Command/input:** Run `npx @replynodes/brand-kit stripe.com` with the source bare domain. **Artifacts:** Review all six files and consume generated `tokens.css` alongside `brand.json`, `colors.json`, `fonts.json`, `logos.json`, and `DESIGN.md`. **Consumer workflow:** Inspect the generated tokens, then adapt them in the existing stylesheet and component system. **Limitations:** Tokens reflect available source signals only, logos are references rather than downloaded assets, missing or partial data remains explicit, and no credentials are requested. ### 4. Reusable brand reference package for slides, reports, and email **Command/input:** Run `npx @replynodes/brand-kit github.com` for the brand being referenced. **Artifacts:** Carry exactly `brand.json`, `colors.json`, `fonts.json`, `logos.json`, `tokens.css`, and `DESIGN.md` with the working materials. **Consumer workflow:** Use the files as a shared reference for names, colors, typography, logo references, and documented caveats across slides, reports, or email templates. **Limitations:** This is not a publishing or asset-delivery service: there are no credentials, no anonymous `/v1` routes, no binary logo downloads, and missing or partial data remains explicit. ### 5. Design handoff or audit **Command/input:** Run `npx @replynodes/brand-kit notion.so` using the audited implementation’s bare-domain input. **Artifacts:** Share exactly the six outputs—`brand.json`, `colors.json`, `fonts.json`, `logos.json`, `tokens.css`, and `DESIGN.md`. **Consumer workflow:** Compare the implementation with the available extracted signals, record decisions against `DESIGN.md`, and pass the package to the next reviewer. **Limitations:** The package does not make customer or design-quality claims, does not infer unavailable values, and does requests no credentials; logo values remain references only and missing or partial data remains explicit. ## Limitations and boundaries - The request needs no API key or signup and makes one aggregate read only; it does not expose or imply anonymous `/v1` routes. - The command accepts or emits no credentials, cookies, sessions, or private tokens. - `logos.json` contains logo references and metadata only; logo binaries are not downloaded. - Missing, partial, or unavailable source data remains explicit in the six outputs. Values are not invented, and a generated file does not imply that a source signal was found. - The CSS handoff consumes generated `tokens.css`; logo values remain references only, and missing or partial data remains explicit. The [canonical Brand Kit repository](https://github.com/replynodes/brand-kit) owns the CLI source. The [Brand intelligence guide](https://docs.replynodes.com/docs/guides/brand-intelligence) owns the aggregate service contract, while the [ReplyNodes API Reference](https://docs.replynodes.com/reference) owns authenticated OpenAPI routes. --- # Google Play > Read public Google Play app metadata and reviews. Source page: https://docs.replynodes.com/docs/guides/google-play # Google Play The `googlePlay` tag covers app details, availability, categories, category apps, data safety, developer listings, permissions, reviews, search, similar apps, and suggestions under `/v1/googleplay/*`. Follow the [API Reference](https://docs.replynodes.com/reference) for each operation's `id`, country, language, pagination, and sorting parameters. Use Google Play search or suggestions to discover an application before requesting details by its store identifier. Detail responses can be enriched with availability, category, data-safety, permission, review, developer, and similar-application operations. Country and language are not cosmetic values: they can affect which listing, release metadata, categories, or reviews are visible. Keep those parameters consistent when an agent compares several calls, and record them alongside the result so a later run can explain a changed answer. Category and developer routes are useful for building bounded research sets, but clients should still apply their own limit and pagination controls rather than attempting an unbounded crawl. All operations in this guide are public, read-only lookups. They do not create reviews, change listings, or access private developer dashboards. The generated [API Reference](https://docs.replynodes.com/reference) defines the exact path, parameter names, required identifiers, and response schema for the deployed contract. When a request fails, preserve the returned `request_id`, respect `Retry-After` for `429`, and retry only safe transient reads with a finite backoff. Do not infer quotas, freshness, or retention promises that are not present in the runtime contract. --- # Guides > Task-oriented paths across implemented capabilities. Source page: https://docs.replynodes.com/docs/guides # Guides Choose a task page: [Web context](https://docs.replynodes.com/docs/guides/web), [Search](https://docs.replynodes.com/docs/guides/search), [YouTube](https://docs.replynodes.com/docs/guides/youtube), [Reddit](https://docs.replynodes.com/docs/guides/reddit), [App Store](https://docs.replynodes.com/docs/guides/app-store), [Google Play](https://docs.replynodes.com/docs/guides/google-play), [Brand intelligence](https://docs.replynodes.com/docs/guides/brand-intelligence), or [Brand Kit](https://docs.replynodes.com/docs/guides/brand-kit). Each page names only operations present in the runtime capability OpenAPI contract, except Brand Kit, which documents its separate local CLI workflow and aggregate boundary. The keyless public loop is **Logo → Brand → Markdown**: successful Logo and Brand responses advertise the next capability in response metadata, while the three dedicated roots remain concise agent-readable guides. These pages are task-oriented entry points, not a replacement for the machine-readable contract. Follow a link to understand the intended workflow, then open the API Reference to select an operation and validate every parameter before making a call. An agent can begin with a broad discovery operation, retain the identifiers and locale returned by that response, and continue with a bounded detail or enrichment request. This sequence keeps the request plan explicit and makes it easier to explain why a result was selected. It also avoids guessing paths from provider names or copying undocumented examples into production automation. The platform exposes public read operations only. A guide may describe data from an external service, but it does not grant permission to publish, modify, authenticate to a third-party account, or bypass an upstream access boundary. Use the deployed capability and OpenAPI documents as the authority for current availability. Preserve `request_id` values, handle errors according to their status and `Retry-After` guidance, and keep retries finite. If a guide and a live contract disagree, trust the live contract and report the discrepancy rather than inventing a route. --- # PDF to Markdown > Convert one public PDF URL to bounded Markdown without signup or an API key. Source page: https://docs.replynodes.com/docs/guides/pdf # PDF to Markdown Direct public HTTP `POST https://pdf.replynodes.com/` requires no account, API key, or cookie when converting one public PDF URL. The MCP `read_document` / `tools/call` at [`https://mcp.replynodes.com/mcp`](https://mcp.replynodes.com/mcp) requires the existing MCP authorization boundary; MCP is not anonymous. `GET /` and `HEAD /` are documentation-only. `POST /` performs the conversion; the allowed methods are `GET`, `HEAD`, and `POST`. The contract limits the source/download to 10 MiB, the document to 50 pages, and each conversion to 60 seconds. Each IP may make 20 requests per hour and run 2 conversions at once. Successful JSON responses are limited to 1 MiB including the response newline; an oversized conversion is rejected with `502 upstream_unavailable` rather than truncated. ```sh curl -X POST https://pdf.replynodes.com/ \ -H 'Content-Type: application/json' \ -d '{"url":"https://public.example/file.pdf"}' ``` The successful response is exactly a document object with `type`, `mime_type`, `markdown`, and `metadata.pages`; `metadata.title` is included when available. The endpoint rejects private/metadata targets, unsafe redirects, non-PDF content, partial results, and malformed input. All errors use the standard `{ "error": { "code", "message", "request_id" } }` envelope. The documented statuses are `400 invalid_request`, `405 method_not_allowed` (`Allow: GET, HEAD, POST`), `413 payload_too_large`, `429 rate_limited`, `502 upstream_unavailable`, `503 degraded`, and `504 gateway_timeout`. Limits are 10 MiB per source/download, 50 pages, 60 seconds, 20 conversions per IP per hour, and two active conversions per IP. Successful bounded responses are cached for 24 hours by normalized URL without its fragment. A cache hit still consumes hourly quota and does not consume an active conversion slot. Redis is shared and mandatory; cache, quota, admission, and Redis failures fail closed. This public HTTP contract is also exposed through the sole MCP application at [`https://mcp.replynodes.com/mcp`](https://mcp.replynodes.com/mcp) as the `read_document` tool. It accepts exactly one top-level `url` input and uses the same PDF to Markdown limits, safety checks, cache, rate limits, concurrency, and error behavior as this POST endpoint. It is intended for read PDF, PDF for AI agents, extract PDF text, and PDF context workflows. --- # Reddit > Read public Reddit posts, subreddits, users, and search results. Source page: https://docs.replynodes.com/docs/guides/reddit # Reddit The `reddit` tag includes post lookup by ID or permalink, post search, subreddit posts, user posts, and user activity. The exact paths and query parameters are generated in the [API Reference](https://docs.replynodes.com/reference); all are read-only `GET` operations. Use post lookup when an agent already has an identifier or permalink, and use search when the topic or phrase is known but the post is not. Subreddit and user routes provide bounded timelines for a named community or public account. Keep the original permalink, subreddit, or username in the job record so the result can be reproduced and so similarly named communities are not silently substituted. Search and activity results are public upstream data and may change as posts are edited, removed, ranked, or made unavailable; a response is therefore a point-in-time observation rather than a permanent archive. The [API Reference](https://docs.replynodes.com/reference) is authoritative for path templates, pagination, limits, and response fields. Do not add OAuth credentials, cookies, sessions, or private-account assumptions to a client: this surface is intentionally read-only and fail-closed when the upstream cannot provide public data. Preserve the returned `request_id` for diagnostics. For transient failures, follow the response status and any `Retry-After` value with a bounded retry policy; do not turn a research request into an unbounded crawl or a high-volume replay. --- # Search > Run normalized public web search. Source page: https://docs.replynodes.com/docs/guides/search # Search `GET /v1/web/search` is the canonical `web_search`-tagged web-search operation. Its OpenAPI parameters include `text`, optional `engines`, `lang`, `region`, `date`, `site`, `limit`, `start`, and `cursor`. Pass only parameters declared by the contract; exact result fields are in the generated [API Reference](https://docs.replynodes.com/reference). Build a search request from the smallest set of constraints that answers the question. `text` is the required query, while `site`, language, region, date, engines, and pagination narrow or reproduce a search plan. Keep the complete parameter set with the result because changing region, language, or engine selection can legitimately produce a different ordering and different documents. Use `limit`, `start`, or `cursor` to page through a bounded set, and stop when the response indicates there are no more useful results. Do not assume that a result is current, complete, or ranked identically on a later request. This route returns normalized public search data and does not provide a private search session or a write operation. The generated [API Reference](https://docs.replynodes.com/reference) defines the envelope and result fields; the deployed runtime capability document is authoritative if availability changes. Preserve `request_id` values for support and observability. Handle `429` with the server's `Retry-After` guidance and use finite retries for transient failures. Avoid replaying the same broad query indefinitely, especially when an agent is paging on behalf of another workflow. --- # Web context > Scrape, map, and crawl public web pages. Source page: https://docs.replynodes.com/docs/guides/web # Web context The `web` tag in OpenAPI exposes three read operations: - `GET /v1/webcontext/scrape` accepts `url` plus optional selector filters and returns page content. - `GET /v1/webcontext/map` accepts `url` and discovers same-site URLs. - `GET /v1/webcontext/crawl` accepts `url`, `max_pages`, and `max_depth` for bounded same-origin crawling. Use the [API Reference](https://docs.replynodes.com/reference) for each operation's parameter and response schema. ## Limiting scrape output The optional `max_chars` parameter is an integer from 1 through 1048576. It counts Unicode code points, not bytes or model tokens; as a rough guide, there are 4 code points per English token. If a longer page is cut, it is cut at the last line break in the second half of the budget; otherwise it is cut at the last whitespace there; otherwise it is cut exactly at the budget. Trailing whitespace is trimmed and nothing is appended. `data.truncated` is a bool, `data.markdown_chars` is the length of the full page Markdown, and `data.links` / `data.images` are listed from the full page rather than the excerpt. The same price applies with or without `max_chars`. A non-integer or out-of-range value returns `400 invalid_request` before any fetch and is not charged. ```sh curl -sS -H "Authorization: Bearer $REPLYNODES_API_KEY" "https://api.replynodes.com/v1/webcontext/scrape?url=https://example.com&max_chars=2000" ``` ## Free markdown by URL (no API key) A no-signup, zero-auth endpoint returns the content of one public page as markdown: ```sh curl -sS https://md.replynodes.com/stripe.com ``` The request is a bare host with an optional path: `https://md.replynodes.com/{domain}` returns the home page and `https://md.replynodes.com/{domain}/{path}` returns a page inside it. The response is `text/markdown; charset=utf-8` — the page's text with its headings, links, and lists kept — so a client can read or store it without an HTML parser. Response headers carry the cache and quota state of the request: `X-Cache` (`hit` when the URL was served from cache, `miss` when the host had to fetch it — the query string is part of the cache key, so repeating a URL with a new query parameter produced a `miss` in testing), `X-RateLimit-Limit` (100), `X-RateLimit-Remaining`, `X-RateLimit-Reset`, and `X-Request-Id`. One request is one page: this endpoint does not crawl, follow links, or paginate, so issue a request per page and use the `webcontext` operations above when you need crawl or map behaviour. A request it cannot serve is answered as the standard JSON error envelope instead of markdown — a host that does not resolve returns `400` `invalid_request` with a `request_id` — so check the status and the content type before storing a response. **`HEAD` describes the same page a `GET` returns.** `curl -I https://md.replynodes.com/stripe.com` answers `200` with the same `content-length` and `content-type` the `GET` returns and no body, so a size or freshness preflight is safe. The quota still treats it as a request: every call, `HEAD` included, spends one unit of the rate limit. ### Output formats Choose the response format with headers; the query string belongs to the target URL. | Request headers | Response `Content-Type` | Body | | --- | --- | --- | | none, `Accept: */*`, `Accept: text/markdown`, `Accept: text/plain` | `text/markdown; charset=utf-8` | Markdown (unchanged) | | `X-Format: frontmatter` | `text/markdown; charset=utf-8` | YAML front matter + Markdown | | `Accept: application/json` (and no `X-Format`) | `application/json` | `{data, meta}` envelope | | `X-Format: markdown` | as the default row | Markdown | | `X-Format` with any other value | `application/json` | `400 invalid_request` | | `Accept: application/json` **and** `X-Format: frontmatter` | `application/json` | `400 invalid_request` (conflicting) | ```sh curl -sS -H 'Accept: application/json' https://md.replynodes.com/stripe.com curl -sS -H 'X-Format: frontmatter' https://md.replynodes.com/stripe.com ``` Each format spends one quota unit. Successful responses set `Vary: Accept, X-Format`. The logo counterpart of this endpoint is documented under [Brand intelligence](https://docs.replynodes.com/docs/guides/brand-intelligence); the product overview for this one is [replynodes.com/markdown-api](https://replynodes.com/markdown-api/). ### Selectors Filter the page with request headers: | Request header | Meaning | Example | | --- | --- | --- | | `X-Include-Selectors` | Keep only matching elements | `article,.post-body` | | `X-Exclude-Selectors` | Remove matching elements | `nav,footer,.sidebar` | Selectors are comma-separated, with at most 10 entries and 512 bytes per header. Duplicates are removed, and control characters or `{` `}` `;` `<` `>` are rejected. Violations return `400 invalid_request` with `reason: bad_option` and spend no quota. A page's main heading may remain in the output even when it matches an exclude selector. ```sh curl -sS -H 'X-Exclude-Selectors: nav,footer' https://md.replynodes.com/stripe.com ``` Filtered and unfiltered pages are cached separately. If a page returns an access-check page with selectors set, the response is `502 upstream_blocked` because the crawl fallback is not used with selectors. ### Errors Every error is the standard JSON envelope with unchanged `error.code` and HTTP status, while two extra fields help a program decide what to do: `error.reason` is a stable value from the table, and `error.retryable` is true when sending the identical request again later can succeed without changing anything; it says nothing about how soon, which `X-RateLimit-Reset` / `Retry-After` provide. | HTTP | `error.code` | `error.reason` | Retryable | What to do | | --- | --- | --- | --- | --- | | 400 | `invalid_request` | `empty_target` | `false` | Provide a target URL. | | 400 | `invalid_request` | `bad_scheme` | `false` | Use `http` or `https`. | | 400 | `invalid_request` | `malformed_url` | `false` | Fix the URL. | | 400 | `invalid_request` | `target_too_long` | `false` | Shorten the URL. | | 400 | `invalid_request` | `target_not_allowed` | `false` | Use a public target. | | 400 | `invalid_request` | `target_rejected` | `false` | The fetcher rejected the URL; check that it is a valid public page. | | 400 | `invalid_request` | `bad_option` | `false` | Fix the option request headers. | | 404 | `not_found` | `route_disabled` | `false` | The free Markdown route is not enabled on this host; use `/v1/webcontext/scrape`. | | 404 | `not_found` | `target_not_found` | `false` | The page does not exist; check the URL. | | 405 | `method_not_allowed` | `method_not_allowed` | `false` | Use `GET` or `HEAD`. | | 429 | `anonymous_limit_reached` | `daily_limit` | `false` | Wait for `X-RateLimit-Reset` or use an API key. | | 451 | `source_excluded` | `publisher_excluded` | `false` | The publisher excludes automated access; contact them for licensing. | | 502 | `upstream_blocked` | `access_check` | `false` | Try another page or contact the publisher. | | 502 | `upstream_unavailable` | `target_unreachable` | `true` | Check the URL or try again later. | | 502 | `upstream_unavailable` | `empty_content` | `false` | Try a text-based page; scanned PDFs and image-only pages have no text. | | 502 | `upstream_unavailable` | `content_too_large` | `false` | Try a smaller page. | | 502 | `upstream_unavailable` | `provider_unavailable` | `true` | Try again later. | | 503 | `degraded` | `service_degraded` | `true` | Try again later. | | 499 | `gateway_timeout` | `client_closed` | `true` | Your client closed the connection; keep it open for up to 33 seconds. | | 500 | `internal_error` | `internal_error` | `true` | Try again later; report the `request_id` if it persists. | | 504 | `gateway_timeout` | `target_timeout` | `true` | Try again later. | ```json { "error": { "code": "upstream_unavailable", "reason": "empty_content", "retryable": false, "message": "The page was fetched but has no extractable text, …", "request_id": "…" } } ``` Reason values are a closed set; new values may be added, but existing ones are never renamed or removed. ## Cross-discovery and returning-caller CTA Successful free responses include `X-ReplyNodes-Discovery: brand` and a `Link` relation to `https://brand.replynodes.com/{domain}` when the target host is known. A valid returning `rn_anon_caller_id` cookie also exposes `X-ReplyNodes-CTA: api-key` and a `Link` relation to `https://platform.replynodes.com/sign-up`. These headers are informational: the cookie is analytics-only, and the first free request remains keyless. --- # YouTube > Read public YouTube channels, videos, playlists, comments, and transcripts. Source page: https://docs.replynodes.com/docs/guides/youtube # YouTube The `youtube` tag exposes read operations for search, channels, videos, playlists, related videos, comments, and transcripts. Paths include `/v1/youtube/search`, `/v1/youtube/channel/{id}`, `/v1/youtube/video/{id}`, `/v1/youtube/playlist/{id}`, `/v1/youtube/related/{id}`, `/v1/youtube/comments/{id}`, and `/v1/youtube/transcript/{id}`. Use the [API Reference](https://docs.replynodes.com/reference) for required identifiers and optional language/limit parameters. Start with search when the agent has a topic or phrase, or begin with a channel, video, or playlist identifier when the source is already known. Use related videos and comments as targeted enrichment steps rather than as an unbounded crawl. Transcript requests may depend on the video's available languages, so keep the requested language and the selected video identifier with the result. Public metadata, comments, and transcripts can change or disappear upstream; record the retrieval time and treat the response as an observation of the public surface at that moment. Every operation is a read-only `GET` request. The [API Reference](https://docs.replynodes.com/reference) defines exact identifiers, optional limits, language parameters, pagination, and response fields; do not infer an undocumented route from a provider URL. Preserve `request_id` values and use bounded retries for safe transient reads. Honor `Retry-After` on `429` responses and do not send credentials, cookies, or private-session data to this public provider surface. If a requested item is unavailable, report the upstream limitation instead of silently substituting a different video or channel. --- # ReplyNodes documentation > The read-only web context API for AI agents. Search, scrape and read public web, social and app data through one REST API or remote MCP server. Source page: https://docs.replynodes.com/docs/ # ReplyNodes documentation ReplyNodes is the read-only web context API for AI agents: search, scrape and read public web, social and app data through one REST API or remote MCP server. The data endpoints read public data. The monitor and watch endpoints manage your own scheduled monitors; nothing here publishes content or posts to social accounts. ## Start here - [Introduction](https://docs.replynodes.com/docs/introduction): what ReplyNodes is and how the pieces fit together. - [Quickstart](https://docs.replynodes.com/docs/quickstart): make your first real read in under a minute. - [Agent quickstart](https://docs.replynodes.com/docs/agent-quickstart): choose REST, an SDK, MCP or an agent skill for your client. - [Authentication](https://docs.replynodes.com/docs/auth): MCP OAuth for interactive clients, API keys for headless and REST use. - [MCP setup](https://docs.replynodes.com/docs/mcp): connect the remote MCP server at `https://mcp.replynodes.com/mcp`. - [API reference](https://docs.replynodes.com/reference): every operation, generated from the canonical OpenAPI document. ## Provider guides - [Web context](https://docs.replynodes.com/docs/guides/web): scrape, map and crawl public web pages. - [Search](https://docs.replynodes.com/docs/guides/search): web search for agents. - [Brand intelligence](https://docs.replynodes.com/docs/guides/brand-intelligence) and [Brand Kit](https://docs.replynodes.com/docs/guides/brand-kit): logos, colors, fonts and social links from a domain. - [YouTube](https://docs.replynodes.com/docs/guides/youtube), [Reddit](https://docs.replynodes.com/docs/guides/reddit), [Apple App Store](https://docs.replynodes.com/docs/guides/app-store) and [Google Play](https://docs.replynodes.com/docs/guides/google-play): public data for research agents. - [PDF](https://docs.replynodes.com/docs/guides/pdf): turn a PDF into Markdown for an agent. ## Machine-readable Agents can read [llms.txt](https://docs.replynodes.com/llms.txt), the full text in [llms-full.txt](https://docs.replynodes.com/llms-full.txt), a Markdown copy of every page (add `.md` to a docs URL) and the [OpenAPI JSON](https://docs.replynodes.com/api/openapi.json). The product site is [replynodes.com](https://replynodes.com/). Use the documentation pages to plan a request, then verify the final operation against the deployed capability and OpenAPI documents. A typical agent workflow is to discover a public resource, retain its identifier and relevant locale, request a bounded detail or enrichment response, and pass the normalized result to the next step. Keep the returned `request_id` with the result so failures and upstream changes can be correlated later. Public provider data can be incomplete, stale, removed, or temporarily unavailable; clients should communicate that uncertainty instead of filling gaps with guessed values. ReplyNodes is a read-only data layer. The documented routes do not publish content, modify external listings, access private accounts, or forward browser sessions. Use finite timeouts and retries, honor `Retry-After` on rate limits, and avoid turning a health check into a broad crawl. If a guide and a live contract disagree, trust the live contract and report the documentation mismatch for correction. --- # Integrations > REST, generated SDK contracts, and agent skills. Source page: https://docs.replynodes.com/docs/integrations # Integrations ## MCP Use the canonical remote server URL, `https://mcp.replynodes.com/mcp`, with an MCP-capable client. Interactive clients use Better Auth MCP OAuth through `https://auth.replynodes.com`; headless clients can use a ReplyNodes API key. See the [MCP guide](https://docs.replynodes.com/docs/mcp) for the two setup paths. Organization context comes from the authenticated identity or key, never from a client-supplied organization id. ## REST Any HTTP client works. Use the base URL from the API contract, bearer authentication, and the exact operation parameters shown in the [API Reference](https://docs.replynodes.com/reference). Read [Errors](https://docs.replynodes.com/docs/production) before adding retries. ## SDKs The monorepo has an OpenAPI Generator setup, not runtime SDK packages. Its target configurations are kept under `sdk-generation/config/` and are generated from the repository's SDK input snapshot. For live route names and schemas, use the runtime capability OpenAPI contract at `https://docs.replynodes.com/api/openapi.json` and re-check it before installing or generating a client. The downstream package names and intended language targets are documented in `sdk-generation/README.md`; installation instructions, auth setup, first requests, pagination, and errors belong to each downstream repository once it is available. Do not invent an install command or client interface for a package that has not been verified. A generated client must preserve bearer auth, GET-only operations, the `{ data, meta }` envelope, and `meta.next_cursor` pagination where an endpoint exposes it. ## Agent skills The catalog under `services/social-data-skills/` generates provider-specific skill packages, MCP schemas, endpoint examples, and `llms.txt` material. Start at its `catalog/README.md`, then use the provider package's `SKILL.md` and `INSTALL.md`. Generated artifacts are not hand-edited; the runtime capability OpenAPI document under `services/replynodes-fetcher/internal/gateway/` is the source used for this docs app's API reference and LLM indexes. --- # Introduction > One read-only gateway for public web and app data. Source page: https://docs.replynodes.com/docs/introduction # Build with public context ReplyNodes is a read-only data gateway for applications and agents that need normalized web extraction, web search, brand intelligence, Reddit, Hacker News, YouTube, Apple App Store, and Google Play reads. Every public data operation is an authenticated HTTP `GET`; provider runtimes are private behind the gateway. The API base URL is api.replynodes.com. Discover live paths in the runtime capability document before making a call. The public [API Reference](https://docs.replynodes.com/reference) is the deployed contract. ## Choose your path - **REST** — use any HTTP client and send a bearer key. - **SDK generation** — the repository contains the OpenAPI Generator boundary for TypeScript, Python, Go, Ruby, and PHP downstream SDKs. Published package repositories are not part of this monorepo; check their availability before adding one to a product. - **MCP** — connect a compatible client to the canonical stateless Streamable HTTP endpoint at [`https://mcp.replynodes.com/mcp`](https://mcp.replynodes.com/mcp); interactive clients use native Better Auth MCP OAuth, and headless or manually configured clients use a ReplyNodes API key. See [MCP](https://docs.replynodes.com/docs/mcp). - **Agent Skill** — use the authoritative generated packages under `services/social-data-skills/generated/` for client-specific instructions and schemas. Public REST reads never accept platform cookies, platform or provider OAuth credentials, or write operations; native Better Auth MCP OAuth is supported only on the MCP endpoint. All public data operations remain read-only. --- # MCP > Connect read-only ReplyNodes tools to MCP clients. Source page: https://docs.replynodes.com/docs/mcp # MCP ReplyNodes provides one enterprise MCP application, powered by `mcp-use`, at: ```text https://mcp.replynodes.com/mcp ``` The same application serves both the human-readable landing page and the Streamable HTTP protocol. It supports native Better Auth MCP OAuth for interactive clients and ReplyNodes API keys for headless or manually configured clients: ```text GET /mcp -> mcp-use landing page POST /mcp -> MCP initialize, tools/list, and tools/call ``` ### Interactive OAuth An MCP client that supports OAuth can start its authorization flow from the remote server URL. Better Auth is the OAuth authority at [`https://auth.replynodes.com`](https://auth.replynodes.com), and the MCP scope is `mcp:read`. The client owns the browser redirect and PKCE flow; do not copy an access token into configuration or prompts. Sign in or manage your [`https://platform.replynodes.com/sign-in`](https://platform.replynodes.com/sign-in) and manage your ReplyNodes organization at [`https://platform.replynodes.com/api-keys`](https://platform.replynodes.com/api-keys). OAuth access is organization-scoped. The client does not provide an organization id; ReplyNodes resolves the organization from the authenticated identity and enforces credits, entitlements, metering, and read-only access. ## Connect For a headless agent without a key, follow the [agent claim flow](https://docs.replynodes.com/docs/auth) or the full protocol at [https://replynodes.com/auth.md](https://replynodes.com/auth.md) first. For headless, CI, or clients without OAuth support, configure the remote server URL and store a ReplyNodes API key as a secret. The exact UI or config file varies by client; use the client's equivalent of: ```json { "url": "https://mcp.replynodes.com/mcp", "headers": { "Authorization": "Bearer ${REPLYNODES_API_KEY}" } } ``` The placeholder is illustrative configuration syntax: use the secret mechanism documented by your client, and never paste a real key into a committed file. ## Credits and package pricing Authenticated MCP calls use the same prepaid package credits as the REST API. The current ReplyNodes packages are: | Package | Included credits | Price | | --- | ---: | ---: | | Free | 500 one-time credits | Free | | Developer | 10,000 credits/month | $19/month | | Pro | 100,000 credits/month | $99/month | Per-call credit usage is determined by the canonical capability and pricing contract; the MCP client cannot set or override a price. Review package access Review package access and organization billing from [`https://platform.replynodes.com/api-keys`](https://platform.replynodes.com/api-keys). ## Tool contract The MCP tool catalog is generated from the canonical runtime capabilities OpenAPI contract at `services/replynodes-fetcher/internal/gateway/capabilities.openapi.json`. Provider tool arguments map to read-only REST `GET` operations; monitor tool arguments map to the lifecycle operations under `/v1/monitors`, merged into the MCP catalog from the monitor contract at `api-docs/replynodes-fetcher.openapi.json`. Company Changes is merged from the same contract, but MCP exposes exactly four read tools: `get_company_events`, `get_company_history`, `get_recent_company_events`, and `get_company_intelligence`. No CCI write tool is discoverable. Provider tool calls are forwarded to `https://api.replynodes.com`. Monitor and Company Changes calls whose path begins `/v1/monitors`, `/v1/watches`, `/v1/events`, `/v1/entities`, or `/v1/intelligence` are forwarded to the private monitor service origin configured by `MONITOR_API_ORIGIN`; the signed gateway/OAuth handoff is preserved. The configured origin is enforced fail-closed before any caller `Authorization` header is forwarded: only loopback/private hosts are accepted (`localhost`, `*.localhost`, or a private/loopback/link-local IP literal — IPv4 and IPv6, including IPv4-mapped IPv6 such as `::ffff:7f00:1`, excluding the cloud-metadata band 169.254.169.0/24 including 169.254.169.254); public hosts and unapproved DNS names are rejected, so the private monitor service must be reachable by private IP or localhost. The public OpenAPI server URL remains `https://api.replynodes.com` for external API consumers. The Go gateway remains the authority for authentication, OrganizationID, entitlement, credits, metering, rate limits, cache, provider execution, and normalized errors. The TypeScript MCP application does not duplicate those rules. `MONITOR_API_ORIGIN` is resolved lazily, only when a monitor tool call needs it: a deployment without monitor integration keeps serving every provider tool normally, and an unconfigured or unapproved monitor origin fails only the monitor call closed (`monitor_api_misconfigured`) before any caller `Authorization` is forwarded. The PDF capability is the sole MCP PDF tool, named `read_document`. It accepts one top-level `url` containing a public PDF URL and forwards the canonical `POST https://pdf.replynodes.com/` request. Its description supports discovery for PDF to Markdown, read PDF, PDF for AI agents, extract PDF text, and PDF context. The public PDF contract remains authoritative for its limits and errors. ### Monitor tool credentials Standard MCP OAuth (`mcp:read`) maps only to the monitor service's read operations (`monitor_list`, `monitor_get`, `monitor_changes`, `monitor_runs`) and the four CCI read tools through the `monitors:read` scope. The write tools (`monitor_create`, `monitor_update`) require `monitors:write`, which the standard MCP OAuth path never grants: use a ReplyNodes `rn_test_*` / `rn_live_*` API key in the `Authorization` header for monitor writes. An OAuth-authenticated client that calls a write tool receives `403 forbidden_scope`; that is the intended fail-closed behavior, not a transient error. Monitor HTTP calls are rate-limited per organization by the monitor service itself — 60 requests/min for the write bucket (create and update, where update also covers pausing) and 300 requests/min for the read bucket (get/list/history) by default — independent of the gateway's provider quotas. Exhausted windows return `429 rate_limited` with `Retry-After` and `X-RateLimit-*` headers; when the limiter itself cannot reach its database the call fails closed with `503 degraded`. Scheduled monitor execution is governed by the monitor scheduler and is not counted against those HTTP limits. Two prerequisites for the public monitor contract remain outside this repository and are not implemented here: the edge/router must map `https://api.replynodes.com/v1/monitors` to the privately bound monitor service, and the control plane that issues `rn_*` API-key scopes must mint `monitors:read`/`monitors:write`. Until the scope issuance ships, API-key monitor calls fail closed with `403 forbidden_scope`. ## Verify Use the client's MCP initialize flow, then inspect `tools/list` and call one harmless read-only tool. Authentication is forwarded to the REST gateway; an unauthenticated request cannot execute a tool. The available capability groups can change with the gateway contract. Read the canonical capabilities/OpenAPI artifact before relying on a particular tool. ## Troubleshooting - `401`: confirm the client completed native Better Auth MCP OAuth, or that it sends an `Authorization` header with a valid ReplyNodes API key. - `404`: confirm the URL is exactly `https://mcp.replynodes.com/mcp`. - `400`: validate the JSON-RPC request, MCP protocol version, tool name, and declared arguments. - `429`: honor `Retry-After` and reduce concurrency. --- # Production > Authentication, reliability, and security boundaries. Source page: https://docs.replynodes.com/docs/production # Production Read the [authentication and response rules](https://docs.replynodes.com/docs/production) in the main production guide, then see [Operations](https://docs.replynodes.com/docs/production/operations) for safe retries, correlation, and undocumented limits. Production clients should begin by reading the main production guide before integrating an endpoint. It explains the accepted authentication forms, the response envelope, and the boundary between the public read API and the external platforms it observes. Select routes from the runtime capability document or generated OpenAPI contract instead of hard-coding assumptions from an old example. Keep the organization or API-key context used for a request under the caller's control, and never derive tenant identity from a client-supplied label or from an external provider identifier. This service is intentionally read-only. It does not publish to social platforms, change app-store listings, submit Reddit content, or expose private browser sessions. Public data can be stale, removed, rate-limited, or unavailable upstream, so production workflows should surface uncertainty rather than promising freshness or completeness. Preserve each response's `request_id`, classify errors by HTTP status, and use the operations guide for safe retry behavior. When deployed behavior and a copied snippet disagree, the live capability and OpenAPI documents are authoritative; capture the discrepancy for follow-up instead of guessing. --- # Operations > Operate clients safely in production. Source page: https://docs.replynodes.com/docs/production/operations # Production operations Use bounded timeouts, preserve the returned `request_id` for support, honor `Retry-After` on `429`, and retry only safe transient reads. Do not assume quotas, SLAs, freshness, or retention periods: the repository does not publish those values. The runtime capability OpenAPI document served at `/api/openapi.json` remains authoritative for deployed path and schema compatibility. Make retries explicit in the client: cap the number of attempts, use a finite backoff, and stop when the response indicates an invalid request, an authorization failure, or an upstream result that is not safely repeatable. Idempotent public reads can usually be retried after a connection reset or a transient server error, but a retry does not make the underlying provider data fresher or more complete. Log the endpoint, status, elapsed time, and `request_id` without logging credentials, cookies, or private payloads. Correlate repeated failures by request ID and time window before escalating them. When an integration changes, validate it against the deployed capability and OpenAPI documents rather than a local guess. Check the exact route, parameter spelling, required identifiers, pagination behavior, and response envelope. Keep a small, bounded smoke request for operational checks and avoid broad crawls as a health probe. This service exposes read-only data through provider boundaries; it does not authorize writes or grant access to private third-party accounts. If a provider is unavailable, preserve the error classification and tell downstream agents that the data is unavailable instead of fabricating an empty success response. --- # Quickstart > Make your first real read in under a minute. Source page: https://docs.replynodes.com/docs/quickstart # Quickstart If you are evaluating the free Logo -> Brand -> Markdown loop from the owned documentation channel, use the measured sign-up entry point: [`platform.replynodes.com/sign-up`](https://platform.replynodes.com/sign-up?source=docs&utm_medium=owned&utm_campaign=free-loop). The existing first-party handoff is bounded and expires after 30 days. ## MCP clients For an interactive MCP client, add `https://mcp.replynodes.com/mcp` as a remote server. The client can discover the native OAuth flow and authenticate through Better Auth at [`https://auth.replynodes.com`](https://auth.replynodes.com). Use the `mcp:read` scope when the client asks for scopes. No organization id is needed; the authenticated organization supplies the tenant context. Manage your ReplyNodes access at [`https://platform.replynodes.com/sign-in`](https://platform.replynodes.com/sign-in) and manage access at [`https://platform.replynodes.com/api-keys`](https://platform.replynodes.com/api-keys). For headless clients or manual configuration, first use the [agent claim flow](https://docs.replynodes.com/docs/auth) if you do not have a key, then use the API-key setup in the [MCP guide](https://docs.replynodes.com/docs/mcp). Set `REPLYNODES_API_KEY` in your shell from a secret store. The HTTP API receives it only in the `Authorization` header. Keep it server-side; do not commit it or put it in browser code. ```bash : "${REPLYNODES_API_KEY:?Set REPLYNODES_API_KEY in your secret store}" ``` Fetch a public page as clean Markdown. This is the canonical `webcontext` scrape operation in the OpenAPI contract: ```bash curl -sS \ -H "Authorization: Bearer ${REPLYNODES_API_KEY}" \ "https://api.replynodes.com/v1/webcontext/scrape?url=https%3A%2F%2Freplynodes.com" ``` Successful responses use the `{ data, meta }` envelope. `meta.request_id` is always present. Errors use `{ error: { code, message, request_id } }`. ## Add correlation Send an opaque request id when you need to connect a client log to a support investigation: ```bash curl -sS \ -H "Authorization: Bearer ${REPLYNODES_API_KEY}" \ -H "X-Request-Id: demo-scrape-001" \ "https://api.replynodes.com/v1/webcontext/scrape?url=https%3A%2F%2Freplynodes.com" ``` For parameters, response schemas, and every available provider operation, use the [API Reference](https://docs.replynodes.com/reference). It is generated from the runtime capability contract, not hand-maintained endpoint prose.